From: Kevin Townsend Date: Tue, 3 May 2011 11:34:19 +0000 (+0200) Subject: Initial commit X-Git-Url: https://git.rohieb.name/hackover2013-badge-firmware.git/commitdiff_plain/9d18e10afb2439a6a9ba6978a799259746a837b7 Initial commit --- 9d18e10afb2439a6a9ba6978a799259746a837b7 diff --git a/ChangeLog.txt b/ChangeLog.txt new file mode 100644 index 0000000..3280b0d --- /dev/null +++ b/ChangeLog.txt @@ -0,0 +1,384 @@ +v0.9.2 - Ongoing +================ + +- Added lcdDrawPixels() to lcd.h and the current lcd + drivers to render rows of raw lcd data much quicker + than addressing consecutive pixels individually. + Can be used with windowing in future for fast + animation, continuously writing raw pixels in a + 32x32 pixel frame, etc. +- Fixed ili9328SetWindow() and ili9325SetWindow(). + They can now be used for fast screen paints of + restricted areas of the screen, such as animations + where raw pixel data is constantly fed to the LCD. +- Fixed pixel overflow bugs in drawCircleFilled(). Any + pixels that exceed screen limits will now be dropped, + though at the expense of slightly slower code. +- Added drawLineDotted() to drawing.c to draw lines with + a fixed pattern of empty and solid pixels +- Added __resetBootloader() macro to lpc134x.h to + reset and enter the USB bootloader (LPC1343 Reference + Design Base Board only since this depends on the + existance of the RC combination on the ISP pin). + To reset and executre code normally, the watchdog + time can be used (see "core/wdt"). +- Added AIRCR register to lpc134x.h (Application Interrupt + and Reset Control Register). +- Added drawIcon16() to drawing.c to render monochrome + 16x16 pixel icons from a byte array. +- Added a handful of common 16x16 icon definitions in + /drivers/lcd/icons16.h ... adapted from Gentleface + Toolbar Icon Set. For license terms see + http://www.gentleface.com/free_icon_set.html +- Added a few basic RGB565 color schemes to colors.h and + an image file showing the colors in /tools/colors_h.png +- Updated alphanumeric dialogue form to use new buttons. +- Rewrote drawButton() to use rounded rectangle and + all colors are now passed in as parameters. Also + modified the button command in the CLI to match this. +- Rewrote drawProgressBar() to take advantage of the + new rounded rectangle function (below). Also + modified the progress bar command in the CLI to + allow more colors to be indicated when rendering. +- Added drawRectangleRounded() to drawing.c (filled + rectangle with configurable rounded corners). +- Added drawArrow() to drawing.c to make small rectangles + for left/right menu items, etc. +- Completely rewrote the touch screen calibration code to + be much more accurate. + +v0.9.0 - 28 March 2011 +====================== + +- Calibration process no longer starts automatically when + calibration data is not found in EEPROM. tsCalibrate() + now needs to called manually or from the CLI. +- Fixed a bug in cmd_tswait.c when no delay was passed. +- Added CLI command to set touch screen threshold + to register a touch event (since this can vary from + screen to screen). Type 'x' at the CLI to get/set + the value. The setting is persisted to EEPROM, and if + no value is found on EEPROM CFG_TFTLCD_TS_DEFAULTTHRESHOLD + from projectconfig.h is used. +- Adjusted touch screen code to check ADC values twice + and compare. If mismatch occurs, and error is returned. + This provides far more consistent TS values at the + expense of having to check the error results. See + 'alphanumeric.c' for an example of doing this + correctly. +- Added seperate driver for ILI9328 based displays, even + though it seems to be identical to the ILI9325. Files + were seperated in case the initialisation needs to be + tweeked later or if incompatibilities are found. +- Added the ability to write the contents of the LCD + to a bitmap image, though it's very slow reading data + pixel by pixel and converting it to 24-bit RGB values. + Performance can definately be improved. +- Added 'drawRGB565toBGRA32' to drawing.c to convert + RGB565 colors back to the canonical BGRA32 format +- Added gain controls to TSL2561 driver to increase or + decrease sensitivity. Should be easy to implement + auto-gain functionality now. +- Changed USB VID to a valid value. Source files and + lpc134x-vcom.inf updated accordingly. +- Moved USB VID and PID to projectconfig.h +- Added '-mcpu' flag to the linker in Makefile (the wrong + libm was being linked because of this). + + WARNING + -------------------------------------------------------- +- Some config settings in EEPROM were relocated in v0.90+ + of the LPC1343 Code Base to take into account the new + touch screen calibration code. See projectconfig.h + for more details of the new EEPROM layout. + +v0.8.6 - 21 March 2011 +====================== + +- Added DWT section to LPC134x.h (see Cortex-M3 + Technical Reference Manual section 8.3) +- Added CPU_RESET_CYCLECOUNTER to cpu.c to do rough + in-code performance checks (counts CPU cycles) +- Added '-lm' to linker in Makefile for math.c support +- Increased MAX_STRING_SIZE from 100 to 255 in stdio.c +- Added driver for the TCS3414 RGB color sensor +- Added driver for the TSL2561 digital light sensor +- Added CFG_USBCDC_BUFFERSIZE to projectconfig.h + instead of cdc_buf.h. +- Added a PWM example using a piezo buzzer (see + 'tools/examples/basics/pwm_piezobuzzer' for details) +- Added ctype.c to 'core/libc' +- Changed Crossworks project to use libc files from + 'core/libc' and modified the USB CDC printf to be + much faster by redirecting inside 'puts' rather than + '__putchar' (see 'sysinit.c'). +- Fixed a bug in LPC134x.h ... USB_CMDCODE write and read + masks were reversed +- Added a simple example of reading the card ID from an + ISO14443A (Mifare Classic, etc.) card using the PN532 + ('/tools/examples/sensors/pn532/ISO14443A_ID'). +- Added an 'lcd' folder to 'tools/examples' showing how to use + the generic lcd drawing routines, the touch-screen, etc. +- Rewrote part of the touch screen calibration code to get more + accurate results. Each point is now tested twice and the + results are averaged. Values beyond a certain limit are also + rejected to ignore wacky readings. +- Added a preliminary PN532 (NFC/RFID) driver. Currently UART + only, and only allows simple commands to be sent and received. + By default, all data is fed out to the console via printf. + Will be elaborated and expanded in future releases. +- Cleaned up the ILI9325 TFT LCD driver a bit, adding a proper + enum for the commands, etc. + + +v0.8.5 - 7 March 2011 +===================== + +- Fixed a problem with GDB script when deploying firmware + with Segger J-Link in CodeLite. Code will now deploy + and start executing properly when F5 is pressed (assuming + the Segger GDB Server software is running in the background). +- Interrupts are now disabled while feeding the watchdog as per + a warning in the usermanual. +- Changed fonts for TTF LCDs. DejaVu Sans 9 is now used by default + in the LPC1343 Code Base. The following open source fonts have + been converted using The Dot Factory (see '/tools/dotfactory') and + can be found in '/drivers/lcd/tft/fonts': + + FONT NAME WIDTH + ------------------------------- ---------- + - Bitstream Vera Mono 9 Fixed (8) + - Bitstream Vera Mono 9 Bold Fixed (8) + - Bitstream Vera Mono 11 Fixed (9) + - Bitstream Vera Mono 11 Bold Fixed (9) + - DejaVu Sans 9 Variable + - DejaVu Sans 9 Bold Variable + - DejaVu Sans Condensed 9 Variable + - DejaVu Sans Mono 8 Fixed (8) + - DejaVu Sans Mono 8 Bold Fixed (8) + +- Modified projectconfig.h to select the target board and configure + the project accordingly. This isn't ideal, but it's a lot more + maintainable than have a seperate code base for every board since + they share 95% of the same code. +- Modified WDT code to use the WDT oscillator (rather than the + external crystal) +- Fixed a bug when waking up from sleep in Chibi. Removed systick + delay when toggling reset and slptr pins since this was causing + a blocking condition with the wakeup ISR. +- Added an example of how to retrieve the MCU's unique + 128-bit serial number using IAP (core/iap) +- Added an option to projectconfig.h to select which pin to use for + SCK on SSP0, since the QFN33 package doesn't have all the same + pins. +- Updated Chibi to v0.91 (adds sleep method and promiscuous mode to allow + Chibi to act as an 802.15.4 packet sniffer, etc.). +- Added lcdProperties_t to lcd.h to indicate the properties of different + LCDs (to determine if there is a touch screen present, whether the + screen orientation can be changed, etc.) +- Added basic ST7735 LCD driver (128x160 pixel TFT LCD using 6-pin + SPI-esque interface). Work in progress (no orientation support, etc.). +- Added some simple examples in the 'tools/examples' folder. + +v0.80 - 27 Jan 2011 +=================== + +- Added optimised lcdDrawVLine using orientation + though this should only be used on lines + greate than 20 pixels or so to see any real + advantage +- Added cmd_uart to allow the HW UART speed + to be set in EEPROM (between 9600 and + 115200). Use the 'U' command. +- Updated Crossworks projects files to use + custom printf in 'core/libc' (gains about + 1.3KB in release mode) +- Added driver for SSD1306 OLED displays + to '/drivers/bitmap/ssd1306' +- Changed commands in the CLI to single + characters and shortened descriptions + to save flash space (~0.7KB) +- Updated ILI9325 to allow the screen + orientation to be changed to portrait + of landscape mode. +- Added cmd_orientation to change the LCD + orientation from the CLI +- Fixed a bug in the PMU Wakeup interrupt + handler +- Added a circular buffer for outgoing CDC + data (cdc_buf.c) since you can only feed one + frame per ms (max 64 bytes). The speed needs + to be improved finding the right balance + between caching data and sending it to the EP, + but this should avoid any dropped characters. + More testing will be needed to improve this. +- Fixed a bug with the USB CDC buffer +- Added SILENTMODE to the CLI to disable the + command prompt and echo of input characters + (see CFG_INTERFACE_SILENTMODE). Useful + when another MCU is use the CLI rather than + a human. +- Added IRQ pin to the CLI to indicate when a + command is being processed (pin = low) and + when it has completed or a new command can + be processed (pin = high). +- Added 'cmd_tswait' to wait for a touch event +- Removed 'drivers/nfc/pn532' until proper drivers + can be written +- Added 'cmd_text' and 'cmd_textw' to the CLI to + render text on the LCD and get the width in + pixels of the specified text before rendering. + +v0.70 - 18 Dec 2010 +=================== + +- Added 'calibrate' and 'gettext' commands to the CLI +- Added a dialogue box for the TFT LCD/Touchscreen + to input alpha-numeric data and return the + results as a string ('drivers/lcd/tft/dialogues/*') +- Added touch screen calibration code and UI + ('drivers/lcd/tft/touchscreen.c') +- Fixed a bug in ILI9325.c to make sure that the LCD + is reset during initialisation +- ** IMPORTANT ** Changed 'core/i2c/*' to fix a number + of bugs (thanks Rob65!) ... though this means all + i2c peripherals and drivers will need to be tested. +- Added 'colorscheme_t' to drawing.h to try to use a + standard color palette across GUI controls and make + it easy to change later. Currently only the button + and progress bar make use of this. +- Added 'lcdBacklightOn()' and 'lcdBacklightOff()' to + lcd.h +- Added 'CFG_TFTLCD_TS_THRESHOLD' to projectconfig.h + to configure touch-screen sensitivity when waiting + for a touch event +- Modified 'core/gpio/gpio.c' to reduce the compiled code + size. Repetitive switches where only the registers + change were modified to use temporary registers and + execute the code only once. +- Added the source and binaries for TheDotFactory to + 'tools/dotfactory' for convenience sake. See: + http://www.pavius.net/downloads/tools/53-the-dot-factory +- Removed 'drivers/lcd/tft/tscalibration.c' and moved + the relevant code to touchscreen.c +- Removed the imgconv tool from 'tools/imgconv' (see + point below for more information) +- Removed the previous custom image code and replaced + it with 24-bit Windows bitmap files. This is a bit + slower (since 24-bit data needs to be converted to + RGB565 for each pixel and rows are rendered bottom + up making pixel drawing harder to optimise) but + converting and eventually saving images is easier. + The current code is functional but needs to be + heavily optimised. +- Made some minor optimisations to the data and cmd + functions in the ILI9325 driver. Other functions + need to be optimised as well, but these two should + be close to optimal now. Currently 25 cycles + compiled with -Os, 36 cycles with no optimisation. +- Added 'projects/command/drawing/cmd_bmp.c' to load + 24-bit Windows bitmap images from the SD card and + display them on the TFT LCD. +- Added some schematics to '/tools/schematics' to + show the assumed pin configurations + +v0.60 - 8 December 2010 +======================= + +- Added a number of CLI commands for the TFT LCD + (see 'project/commands/drawing') +- Modified FCLK_FAST() in 'drivers/fatfs/mmc.c' to set + the max speed to 6.0MHz for improved reliability. + Tested with a 4GB microSD card, 300KB/s can be read + using a 512 byte read buffer. +- Modified Chibi to use 16-bit timer 0 for us delays + (more accurate) +- Added a number of commands to + '/projects/commands/drawing' for basic TFT LCD + operations. Removed 'lcd-test.c' and 'lcd-fill.c'. +- Added a flag to projectconfig.h to make FATFS read-only + (to save a couple KB when space is tight). +- Moved 'project/eeprom.*' to 'drivers/eeprom' to add a + level of abstraction to eeprom access throughout the code +- Added a table to projectconfig.h to manage eeprom + addresses. First 256 byte of eeprom should be reserved + for this. +- Added 'drivers/lcd/tft/colors.h' to keep all common + 16-bit RGB565 color definitions in one location +- Added some sample images to 'tools/imgconv' that can + be used to render a basic clock on a TFT LCD screen + (using drawImageFromFile in 'drivers/lcd/tft/drawing.c') +- Modified the makefile to automatically run './lpcrc' + post-build +- Added drawButton() to 'drivers/lcd/tft/drawing.c' +- Updated 'drivers/lcd/tft/touchscreen.c' to do basic + debouncing. tsReadZ() was added to detect pressure on + the touch screen, and tsWaitForEvent() will only exit + when the pressure passes a minimum threshold. (Thanks + to Limor for pointing out some code by Rossum for this.) +- Fixed some off-by-one pixel errors in cmd-test and + elsewhere + +v0.51 - 27 November 2010 +======================== + +- Added simple RSA encryption/decryption driver. Currently limited to + using 64-bit and 32-bit numbers in key pairs, which isn't terribly secure, + but allows much smaller code size than if huge number support was included. +- Added a driver for the MCP4725 I2C DAC (see "drivers/dac/mcp4725"). +- Moved 'rom_drivers.h' from 'core/usbhid-rom' to 'core' since it can be used + for usbmsd-rom as well if it is implemented at a later date. +- ili9325ReadData() added to ili9325.c by Adafruit Industries (thanks!) +- Modified FCLK_FAST() in 'drivers/fatfs/mmc.c' to set fast SPI speed + to 18MHz instead of the previous 4MHz. This allows for slightly faster + rendering of bitmap images from SD cards, amongst other things. +- Fixed ILI9325 driver to use 0,0 based pixels and not 1x1, meaning the + pixel co-ordinates are 0..239 for X and 0..319 for Y. There may still be + some off-by-one pixel issues that need to be further tested. + +v0.50 - 26 October 2010 +======================= + +- Moved command.c and cmd_tbl.h to /project to try to keep all + project-specific files in one location to improve code-sharing and make + upgrading easier +- Created seperate .c files for every command for the command-line interface + to make it easier to maintain and share code between projects. All commands + listed in cmd_tbl.h are now stored in their own files in /project/commands + (ex.: "/project/commands/cmd_hello.c", etc.) +- Added a CLI command to demonstrate how to draw to the ILI9325 TFT LCD +- Added a CLI command to show the contents of any directory from the SD card + (/project/commmands/cmd_sd_dir.c) +- Added a CLI command showing how to enter deep-sleep and exit with a SW + wakeup (/project/commands/cmd_deepsleep.c). Please note that the wakeup + will not work if you are using USB for the CLI. To see the wakeup message, + you must use UART for the CLI, which is selected by uncommenting + CFG_PRINTF_UART in projectconfig.h +- Fixed pmu.c to set the core clock back to an appropriate state after wakeup +- Added simple wrapper for eeprom access (projects/eeprom.c) +- Reorganised drivers/lcd to take into account non TFT LCD displays. +- Added a preliminary (experimental) driver for 128x64 pixel ST7565-based + bitmap LCDs (ex: Adafruit Industries - http://bit.ly/9xj5vw) ... based on a + driver from Limor Fried at Adafruit +- Numerous bug fixes added by Roel Verdult (Linux compatibility, GCC warnings, etc.) +- Added stub files for PN532 driver (/drivers/nfc/pn532), and added CFG_PN532 to + projectconfig.h as an option +- Added a simple pwm example using 16-bit timer 1 and p1.9 (MAT0) for the output. PWM can be used + to drive stepper motors, or to dim LEDs by adjusting the duty-cycle, etc. The example can be + found in "/core/pwm" +- Added a bi-polar stepper motor driver based on the Arduino library. Basic position data was added + to detece deviation from the 'Home' position and to retrieve the spindle's current angle. See + "drivers/motor/stepper" for more information. +- Added test firmware for the UART and USBCDC CLI (tools/testfirmware) +- Added a table to projectconfig.h to try to keep track of pin and peripherals + usage by drivers and the included SW examples. +- Reorganised some pins used by drivers to avoid pin conflicts. +- Modified core/timer16/timer16.c to allow PWM output to be stopped after a + certain number of pulses have been sent out. + + KNOWN ISSUES + +- The SPI code needs to be modified to allow several SPI devices to be safely + connected on the same bus. At present, this has not been tested since the + SSP/SPI blocks are used exclusively in the current drivers. + \ No newline at end of file diff --git a/License.txt b/License.txt new file mode 100644 index 0000000..655e9a4 --- /dev/null +++ b/License.txt @@ -0,0 +1,27 @@ +Software License Agreement (BSD License) + +Unless otherwise noted, Copyright (c) 2010, microBuilder SARL. +Portions Copyright (c) 2010 Roel Verdult. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..57e7680 --- /dev/null +++ b/Makefile @@ -0,0 +1,180 @@ +########################################################################## +# User configuration and firmware specific object files +########################################################################## + +# The target, flash and ram of the LPC1xxx microprocessor. +# Use for the target the value: LPC11xx, LPC13xx or LPC17xx +TARGET = LPC13xx +FLASH = 32K +SRAM = 8K + +# For USB HID support the LPC134x reserves 384 bytes from the sram, +# if you don't want to use the USB features, just use 0 here. +SRAM_USB = 384 + +VPATH = +OBJS = main.o + +########################################################################## +# Project-specific files +########################################################################## + +VPATH += project +OBJS += commands.o + +VPATH += project/commands +OBJS += cmd_chibi_addr.o cmd_chibi_tx.o cmd_uart.o +OBJS += cmd_i2ceeprom_read.o cmd_i2ceeprom_write.o cmd_lm75b_gettemp.o +OBJS += cmd_sysinfo.o cmd_sd_dir.o cmd_tswait.o cmd_orientation.o +OBJS += cmd_tsthreshhold.o + +VPATH += project/commands/drawing +OBJS += cmd_button.o cmd_circle.o cmd_clear.o cmd_line.o cmd_pixel.o +OBJS += cmd_progress.o cmd_bmp.o cmd_gettext.o cmd_calibrate.o +OBJS += cmd_text.o cmd_textw.o cmd_rectangle.o + +########################################################################## +# Optional driver files +########################################################################## + +# Chibi Light-Weight Wireless Stack (AT86RF212) +VPATH += drivers/chibi +OBJS += chb.o chb_buf.o chb_drvr.o chb_eeprom.o chb_spi.o + +# 4K EEPROM +VPATH += drivers/eeprom drivers/eeprom/mcp24aa +OBJS += eeprom.o mcp24aa.o + +# LM75B temperature sensor +VPATH += drivers/sensors/lm75b +OBJS += lm75b.o + +# TFT LCD support +VPATH += drivers/lcd/tft drivers/lcd/tft/hw drivers/lcd/tft/fonts +VPATH += drivers/lcd/tft/dialogues +OBJS += drawing.o touchscreen.o bmp.o alphanumeric.o +OBJS += dejavusans9.o dejavusansbold9.o dejavusanscondensed9.o +OBJS += dejavusansmono8.o dejavusansmonobold8.o +OBJS += veramono9.o veramonobold9.o veramono11.o veramonobold11.o +# LCD Driver (Only one can be included at a time!) +OBJS += ILI9328.o +# OBJS += ILI9325.o +# OBJS += st7735.o +# OBJS += st7783.o + +# Bitmap/Monochrome LCD support (ST7565, SSD1306, etc.) +VPATH += drivers/lcd drivers/lcd/bitmap/st7565 +VPATH += drivers/lcd/bitmap/ssd1306 +OBJS += smallfonts.o st7565.o ssd1306.o + +# ChaN FatFS and SD card support +VPATH += drivers/fatfs +OBJS += ff.o mmc.o + +# Motors +VPATH += drivers/motor/stepper +OBJS += stepper.o + +# RSA Encryption/Descryption +VPATH += drivers/rsa +OBJS += rsa.o + +# DAC +VPATH += drivers/dac/mcp4725 +OBJS += mcp4725.o + +# RFID/NFC +VPATH += drivers/sensors/pn532 +OBJS += pn532.o pn532_drvr_uart.o + +# TAOS Light Sensors +VPATH += drivers/sensors/tcs3414 drivers/sensors/tsl2561 +OBJS += tcs3414.o tsl2561.o + +########################################################################## +# Library files +########################################################################## + +VPATH += core core/adc core/cmd core/cpu core/gpio core/i2c core/pmu +VPATH += core/ssp core/systick core/timer16 core/timer32 core/uart +VPATH += core/usbhid-rom core/libc core/wdt core/usbcdc core/pwm +VPATH += core/IAP +OBJS += adc.o cpu.o cmd.o gpio.o i2c.o pmu.o ssp.o systick.o timer16.o +OBJS += timer32.o uart.o uart_buf.o usbconfig.o usbhid.o stdio.o string.o +OBJS += wdt.o cdcuser.o cdc_buf.o usbcore.o usbdesc.o usbhw.o usbuser.o +OBJS += sysinit.o pwm.o iap.o + +########################################################################## +# GNU GCC compiler prefix and location +########################################################################## + +CROSS_COMPILE = arm-none-eabi- +AS = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +SIZE = $(CROSS_COMPILE)size +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +OUTFILE = firmware +LPCRC = ./lpcrc + +########################################################################## +# GNU GCC compiler flags +########################################################################## +ROOT_PATH = . +INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/project + +########################################################################## +# Startup files +########################################################################## + +LD_PATH = lpc1xxx +LD_SCRIPT = $(LD_PATH)/linkscript.ld +LD_TEMP = $(LD_PATH)/memory.ld + +ifeq (LPC11xx,$(TARGET)) + CORTEX_TYPE=m0 +else + CORTEX_TYPE=m3 +endif + +CPU_TYPE = cortex-$(CORTEX_TYPE) +VPATH += lpc1xxx +OBJS += $(TARGET)_handlers.o LPC1xxx_startup.o + +########################################################################## +# Compiler settings, parameters and flags +########################################################################## + +CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin +ASFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -D__ASSEMBLY__ -x assembler-with-cpp +LDFLAGS = -nostartfiles -mthumb -mcpu=$(CPU_TYPE) -Wl,--gc-sections +LDLIBS = -lm +OCFLAGS = --strip-unneeded + +all: firmware + +%.o : %.c + $(CC) $(CFLAGS) -o $@ $< + +%.o : %.s + $(AS) $(ASFLAGS) -o $@ $< + +firmware: $(OBJS) $(SYS_OBJS) + -@echo "MEMORY" > $(LD_TEMP) + -@echo "{" >> $(LD_TEMP) + -@echo " flash(rx): ORIGIN = 0x00000000, LENGTH = $(FLASH)" >> $(LD_TEMP) + -@echo " sram(rwx): ORIGIN = 0x10000000+$(SRAM_USB), LENGTH = $(SRAM)-$(SRAM_USB)" >> $(LD_TEMP) + -@echo "}" >> $(LD_TEMP) + -@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP) + $(LD) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS) + -@echo "" + $(SIZE) $(OUTFILE).elf + -@echo "" + $(OBJCOPY) $(OCFLAGS) -O binary $(OUTFILE).elf $(OUTFILE).bin + $(OBJCOPY) $(OCFLAGS) -O ihex $(OUTFILE).elf $(OUTFILE).hex + -@echo "" + $(LPCRC) firmware.bin + +clean: + rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex diff --git a/Readme.txt b/Readme.txt new file mode 100644 index 0000000..b058eab --- /dev/null +++ b/Readme.txt @@ -0,0 +1,11 @@ +This software is based on the freely available LPC1343 Reference Design available +at www.microBuilder.eu, and is licensed under the BSD license (see license.txt +for details). + +The latest version of the software is always available at the following url: + +http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign/LPC1343CodeBase.aspx + +Online documentation is available at: + +http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign/CodeBaseDocumentation.aspx \ No newline at end of file diff --git a/build/codelite/LPC1343 Workspace.tags b/build/codelite/LPC1343 Workspace.tags new file mode 100644 index 0000000..e2fc66b Binary files /dev/null and b/build/codelite/LPC1343 Workspace.tags differ diff --git a/build/codelite/LPC1343 Workspace.workspace b/build/codelite/LPC1343 Workspace.workspace new file mode 100644 index 0000000..f676a7d --- /dev/null +++ b/build/codelite/LPC1343 Workspace.workspace @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/build/codelite/LPC1343 Workspace.workspace.session b/build/codelite/LPC1343 Workspace.workspace.session new file mode 100644 index 0000000..d0bdde6 --- /dev/null +++ b/build/codelite/LPC1343 Workspace.workspace.session @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/codelite/LPC1343_CodeBase.project b/build/codelite/LPC1343_CodeBase.project new file mode 100644 index 0000000..a7dade6 --- /dev/null +++ b/build/codelite/LPC1343_CodeBase.project @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # Make sure that we are using SWD +monitor interface SWD + +# Set monitor to little endian +monitor endian little + +# Set monitor speed +monitor speed 1000 + +# Reset device +monitor reset + +# Set device ID to LPC1343 +monitor flash device = LPC1343 + +# Enable flash download +monitor flash download = 1 + +# Transfer the firmware to the device +load "../../firmware.elf" + +# Initializing PC and stack pointer +monitor reg r13 = (0x00000000) +monitor reg pc = (0x00000004) + + + + + + + + make clean + make + + + + None + $(WorkspacePath)/../../ + + + + + + + + + + + + + + + + + + + + + + + make clean + make + + + + None + $(WorkspacePath) + + + + + + + + + + + + + + + + + diff --git a/build/codelite/tags b/build/codelite/tags new file mode 100644 index 0000000..f672c5a --- /dev/null +++ b/build/codelite/tags @@ -0,0 +1,4 @@ +rx_data C:\Documents and Settings\Kevin\My Documents\My Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase\main.c /^static chb_rx_data_t rx_data;$/;" variable line:66 +main C:\Documents and Settings\Kevin\My Documents\My Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase\main.c /^int main (void)$/;" function line:70 signature:(void) returns:int +__putchar C:\Documents and Settings\Kevin\My Documents\My Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase\main.c /^void __putchar(char c) $/;" function line:186 signature:(char c) returns:void +puts C:\Documents and Settings\Kevin\My Documents\My Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase\main.c /^int puts ( const char * str )$/;" function line:191 signature:( const char * str ) returns:int diff --git a/build/crossworks/LPC1343_CodeBase.hzp b/build/crossworks/LPC1343_CodeBase.hzp new file mode 100644 index 0000000..0bab7e7 --- /dev/null +++ b/build/crossworks/LPC1343_CodeBase.hzp @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/crossworks/LPC1343_CodeBase.hzs b/build/crossworks/LPC1343_CodeBase.hzs new file mode 100644 index 0000000..0ebdfbc --- /dev/null +++ b/build/crossworks/LPC1343_CodeBase.hzs @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/crossworks/flash_placement.xml b/build/crossworks/flash_placement.xml new file mode 100644 index 0000000..963e460 --- /dev/null +++ b/build/crossworks/flash_placement.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/adc/adc.c b/core/adc/adc.c new file mode 100644 index 0000000..fdf2d30 --- /dev/null +++ b/core/adc/adc.c @@ -0,0 +1,228 @@ +/**************************************************************************/ +/*! + @file adc.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section Description + + SW-based single-channel A/D conversion. If you wish to convert + multiple ADC channels simultaneously, this code will need to be + modified to work in BURST mode. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/adc/adc.h" + + void main (void) + { + cpuInit(); + adcInit(); + + uint32_t results = 0; + while(1) + { + // Get A/D conversion results from A/D channel 0 + results = adcRead(0); + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + + */ +/**************************************************************************/ + +#include "adc.h" + +static bool _adcInitialised = false; +static uint8_t _adcLastChannel = 0; + +/**************************************************************************/ +/*! + @brief Returns the conversion results on the specified ADC channel. + + This function will manually start an A/D conversion on a single + channel and return the results. + + @param[in] channelNum + The A/D channel [0..7] that will be used during the A/D + conversion. (Note that only A/D channel's 0..3 are + configured by default in adcInit.) + + @return 0 if an overrun error occured, otherwise a 10-bit value + containing the A/D conversion results. + @warning Only AD channels 0..3 are configured for A/D in adcInit. + If you wish to use A/D pins 4..7 they will also need to + be added to the adcInit function. +*/ +/**************************************************************************/ +uint32_t adcRead (uint8_t channelNum) +{ + if (!_adcInitialised) adcInit(); + + uint32_t regVal, adcData; + + /* make sure that channel number is 0..7 */ + if ( channelNum >= 8 ) + { + // ToDo: Change this to throw an exception back + channelNum = 0; + } + + /* Deselect all channels */ + ADC_AD0CR &= ~ADC_AD0CR_SEL_MASK; + + /* Start converting now on the appropriate channel */ + ADC_AD0CR |= ADC_AD0CR_START_STARTNOW | (1 << channelNum); + + /* wait until end of A/D convert */ + while ( 1 ) + { + // Get data register results for the requested channel + switch (channelNum) + { + case 0: + regVal = (*(pREG32(ADC_AD0DR0))); + break; + case 1: + regVal = (*(pREG32(ADC_AD0DR1))); + break; + case 2: + regVal = (*(pREG32(ADC_AD0DR2))); + break; + case 3: + regVal = (*(pREG32(ADC_AD0DR3))); + break; + case 4: + regVal = (*(pREG32(ADC_AD0DR4))); + break; + case 5: + regVal = (*(pREG32(ADC_AD0DR5))); + break; + case 6: + regVal = (*(pREG32(ADC_AD0DR6))); + break; + case 7: + regVal = (*(pREG32(ADC_AD0DR7))); + break; + default: + regVal = (*(pREG32(ADC_AD0DR0))); + break; + } + + /* read result of A/D conversion */ + if (regVal & ADC_DR_DONE) + { + break; + } + } + + /* stop ADC */ + ADC_AD0CR &= ~ADC_AD0CR_START_MASK; + + /* return 0 if an overrun occurred */ + if ( regVal & ADC_DR_OVERRUN ) + { + return (0); + } + + /* return conversion results */ + adcData = (regVal >> 6) & 0x3FF; + return (adcData); +} + +/**************************************************************************/ +/*! + @brief Initialises the A/D converter and configures channels 0..3 + for 10-bit, SW-controlled A/D conversion. + + @return Nothing +*/ +/**************************************************************************/ +void adcInit (void) +{ + /* Disable Power down bit to the ADC block. */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_ADC); + + /* Enable AHB clock to the ADC. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_ADC); + + /* Digital pins need to have the 'analog' bit set in addition + to changing their pin function */ + + /* Set AD0 to analog input */ + IOCON_JTAG_TDI_PIO0_11 &= ~(IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK | + IOCON_JTAG_TDI_PIO0_11_FUNC_MASK | + IOCON_JTAG_TDI_PIO0_11_MODE_MASK); + IOCON_JTAG_TDI_PIO0_11 |= (IOCON_JTAG_TDI_PIO0_11_FUNC_AD0 & + IOCON_JTAG_TDI_PIO0_11_ADMODE_ANALOG); + + /* Set AD1 to analog input */ + IOCON_JTAG_TMS_PIO1_0 &= ~(IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK | + IOCON_JTAG_TMS_PIO1_0_FUNC_MASK | + IOCON_JTAG_TMS_PIO1_0_MODE_MASK); + IOCON_JTAG_TMS_PIO1_0 |= (IOCON_JTAG_TMS_PIO1_0_FUNC_AD1 & + IOCON_JTAG_TMS_PIO1_0_ADMODE_ANALOG); + + /* Set AD2 to analog input */ + IOCON_JTAG_TDO_PIO1_1 &= ~(IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK | + IOCON_JTAG_TDO_PIO1_1_FUNC_MASK | + IOCON_JTAG_TDO_PIO1_1_MODE_MASK); + IOCON_JTAG_TDO_PIO1_1 |= (IOCON_JTAG_TDO_PIO1_1_FUNC_AD2 & + IOCON_JTAG_TDO_PIO1_1_ADMODE_ANALOG); + + /* Set AD3 to analog input */ + IOCON_JTAG_nTRST_PIO1_2 &= ~(IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK | + IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK | + IOCON_JTAG_nTRST_PIO1_2_MODE_MASK); + IOCON_JTAG_nTRST_PIO1_2 |= (IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3 & + IOCON_JTAG_nTRST_PIO1_2_ADMODE_ANALOG); + + /* Note that in SW mode only one channel can be selected at a time (AD0 in this case) + To select multiple channels, ADC_AD0CR_BURST_HWSCANMODE must be used */ + ADC_AD0CR = (ADC_AD0CR_SEL_AD0 | /* SEL=1,select channel 0 on ADC0 */ + (((CFG_CPU_CCLK / SCB_SYSAHBCLKDIV) / 1000000 - 1 ) << 8) | /* CLKDIV = Fpclk / 1000000 - 1 */ + ADC_AD0CR_BURST_SWMODE | /* BURST = 0, no BURST, software controlled */ + ADC_AD0CR_CLKS_10BITS | /* CLKS = 0, 11 clocks/10 bits */ + ADC_AD0CR_START_NOSTART | /* START = 0 A/D conversion stops */ + ADC_AD0CR_EDGE_RISING); /* EDGE = 0 (CAP/MAT signal falling, trigger A/D conversion) */ + + /* Set initialisation flag */ + _adcInitialised = true; + + /* Set last channel flag to 0 (initialised above) */ + _adcLastChannel = 0; + + return; +} diff --git a/core/adc/adc.h b/core/adc/adc.h new file mode 100644 index 0000000..29e168d --- /dev/null +++ b/core/adc/adc.h @@ -0,0 +1,47 @@ +/**************************************************************************/ +/*! + @file adc.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + */ +/**************************************************************************/ + +#ifndef _ADC_H_ +#define _ADC_H_ + +#include "projectconfig.h" + +uint32_t adcRead (uint8_t channelNum); +void adcInit (void); + +#endif diff --git a/core/cmd/cmd.c b/core/cmd/cmd.c new file mode 100644 index 0000000..ee5ccf4 --- /dev/null +++ b/core/cmd/cmd.c @@ -0,0 +1,296 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file cmd.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include +#include + +#include "cmd.h" +#include "project/cmd_tbl.h" + +#ifdef CFG_PRINTF_UART +#include "core/uart/uart.h" +#endif + +#ifdef CFG_PRINTF_USBCDC + #include "core/usbcdc/cdcuser.h" + static char usbcdcBuf [32]; +#endif + +#if CFG_INTERFACE_ENABLEIRQ == 1 + #include "core/gpio/gpio.h" +#endif + +static uint8_t msg[CFG_INTERFACE_MAXMSGSIZE]; +static uint8_t *msg_ptr; + +/**************************************************************************/ +/*! + @brief Polls the relevant incoming message queue to see if anything + is waiting to be processed. +*/ +/**************************************************************************/ +void cmdPoll() +{ + #if defined CFG_PRINTF_UART + while (uartRxBufferDataPending()) + { + uint8_t c = uartRxBufferRead(); + cmdRx(c); + } + #endif + + #if defined CFG_PRINTF_USBCDC + int numBytesToRead, numBytesRead, numAvailByte; + + CDC_OutBufAvailChar (&numAvailByte); + if (numAvailByte > 0) + { + numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte; + numBytesRead = CDC_RdOutBuf (&usbcdcBuf[0], &numBytesToRead); + int i; + for (i = 0; i < numBytesRead; i++) + { + cmdRx(usbcdcBuf[i]); + } + } + #endif +} + +/**************************************************************************/ +/*! + @brief Handles a single incoming character. If a new line is + detected, the entire command will be passed to the command + parser. If a text character is detected, it will be added to + the message buffer until a new line is detected (up to the + maximum queue size, CFG_INTERFACE_MAXMSGSIZE). + + @param[in] c + The character to parse. +*/ +/**************************************************************************/ +void cmdRx(uint8_t c) +{ + // read out the data in the buffer and echo it back to the host. + switch (c) + { + case '\r': + case '\n': + // terminate the msg and reset the msg ptr. then send + // it to the handler for processing. + *msg_ptr = '\0'; + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%s", CFG_PRINTF_NEWLINE); + #endif + cmdParse((char *)msg); + msg_ptr = msg; + break; + + case '\b': + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%c",c); + #endif + if (msg_ptr > msg) + { + msg_ptr--; + } + break; + + default: + #if CFG_INTERFACE_SILENTMODE == 0 + printf("%c",c); + #endif + *msg_ptr++ = c; + break; + } +} + +/**************************************************************************/ +/*! + @brief Displays the command prompt. The text that appears is defined + in projectconfig.h. +*/ +/**************************************************************************/ +static void cmdMenu() +{ + #if CFG_INTERFACE_SILENTMODE == 0 + printf(CFG_PRINTF_NEWLINE); + printf(CFG_INTERFACE_PROMPT); + #endif +} + +/**************************************************************************/ +/*! + @brief Parse the command line. This function tokenizes the command + input, then searches for the command table entry associated + with the commmand. Once found, it will jump to the + corresponding function. + + @param[in] cmd + The entire command string to be parsed +*/ +/**************************************************************************/ +void cmdParse(char *cmd) +{ + size_t argc, i = 0; + char *argv[30]; + + argv[i] = strtok(cmd, " "); + do + { + argv[++i] = strtok(NULL, " "); + } while ((i < 30) && (argv[i] != NULL)); + + argc = i; + for (i=0; i < CMD_COUNT; i++) + { + if (!strcmp(argv[0], cmd_tbl[i].command)) + { + if ((argc == 2) && !strcmp (argv [1], "?")) + { + // Display parameter help menu on 'command ?' + printf ("%s%s%s", cmd_tbl[i].description, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + printf ("%s%s", cmd_tbl[i].parameters, CFG_PRINTF_NEWLINE); + } + else if ((argc - 1) < cmd_tbl[i].minArgs) + { + // Too few arguments supplied + printf ("Too few arguments (%d expected)%s", cmd_tbl[i].minArgs, CFG_PRINTF_NEWLINE); + printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + } + else if ((argc - 1) > cmd_tbl[i].maxArgs) + { + // Too many arguments supplied + printf ("Too many arguments (%d maximum)%s", cmd_tbl[i].maxArgs, CFG_PRINTF_NEWLINE); + printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + } + else + { + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set the IRQ pin high at start of a command + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1); + #endif + // Dispatch command to the appropriate function + cmd_tbl[i].func(argc - 1, &argv [1]); + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set the IRQ pin low to signal the end of a command + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0); + #endif + } + + // Refresh the command prompt + cmdMenu(); + return; + } + } + printf("Command not recognized: '%s'%s%s", cmd, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + #if CFG_INTERFACE_SILENTMODE == 0 + printf("Type '?' for a list of all available commands%s", CFG_PRINTF_NEWLINE); + #endif + + cmdMenu(); +} + +/**************************************************************************/ +/*! + @brief Initialises the command line using the appropriate interface +*/ +/**************************************************************************/ +void cmdInit() +{ + #if defined CFG_INTERFACE && defined CFG_INTERFACE_UART + // Check if UART is already initialised + uart_pcb_t *pcb = uartGetPCB(); + if (!pcb->initialised) + { + uartInit(CFG_UART_BAUDRATE); + } + #endif + + #if CFG_INTERFACE_ENABLEIRQ != 0 + // Set IRQ pin as output + gpioSetDir(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, gpioDirection_Output); + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1); + #endif + + // init the msg ptr + msg_ptr = msg; + + // Show the menu + cmdMenu(); + + // Set the IRQ pin low by default + #if CFG_INTERFACE_ENABLEIRQ != 0 + gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0); + #endif +} + +/**************************************************************************/ +/*! + 'help' command handler +*/ +/**************************************************************************/ +void cmd_help(uint8_t argc, char **argv) +{ + size_t i; + + printf("Command Description%s", CFG_PRINTF_NEWLINE); + printf("------- -----------%s", CFG_PRINTF_NEWLINE); + + // Display full command list + for (i=0; i < CMD_COUNT; i++) + { + if (!cmd_tbl[i].hidden) + { + printf ("%-10s %s%s", cmd_tbl[i].command, cmd_tbl[i].description, CFG_PRINTF_NEWLINE); + } + } + + printf("%sCommand parameters can be seen by entering: ?%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); +} diff --git a/core/cmd/cmd.h b/core/cmd/cmd.h new file mode 100644 index 0000000..7dde782 --- /dev/null +++ b/core/cmd/cmd.h @@ -0,0 +1,60 @@ +/**************************************************************************/ +/*! + @file cmd.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __CMD_H__ +#define __CMD_H__ + +#include "projectconfig.h" + +typedef struct +{ + char *command; + uint8_t minArgs; + uint8_t maxArgs; + uint8_t hidden; + void (*func)(uint8_t argc, char **argv); + const char *description; + const char *parameters; +} cmd_t; + +void cmdPoll(); +void cmdRx(uint8_t c); +void cmdParse(char *cmd); +void cmdInit(); + +#endif \ No newline at end of file diff --git a/core/cpu/cpu.c b/core/cpu/cpu.c new file mode 100644 index 0000000..03c6db6 --- /dev/null +++ b/core/cpu/cpu.c @@ -0,0 +1,169 @@ +/**************************************************************************/ +/*! + @file cpu.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Initialises the CPU and any core clocks. By default, the core clock + is set to run at 72MHz. In order to reduce power consumption all pins + are set to GPIO and input by cpuInit. + + @section EXAMPLE + @code + #include "lpc134x.h" + #include "core/cpu/cpu.h" + + int main (void) + { + // Initialise the CPU and setup the PLL + cpuInit(); + + while(1) + { + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "cpu.h" +#include "core/gpio/gpio.h" + +/**************************************************************************/ +/*! + @brief Configures the main clock/PLL + + The speed at which the MCU operates is set here using the SCB_PLLCTRL + register, and the SCB_PLLCLKSEL register can be used to select which + oscillator to use to generate the system clocks (the internal 12MHz + oscillator or an external crystal). + + @param[in] multiplier + The PLL multiplier + +*/ +/**************************************************************************/ +void cpuPllSetup (cpuMultiplier_t multiplier) +{ + uint32_t i; + + // Power up system oscillator + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSOSC_MASK); + + // Setup the crystal input (bypass disabled, 1-20MHz crystal) + SCB_SYSOSCCTRL = (SCB_SYSOSCCTRL_BYPASS_DISABLED | SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ); + + for (i = 0; i < 200; i++) + { + __asm volatile ("NOP"); + } + + // Configure PLL + SCB_PLLCLKSEL = SCB_CLKSEL_SOURCE_MAINOSC; // Select external crystal as PLL clock source + SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source + SCB_PLLCLKUEN = SCB_PLLCLKUEN_DISABLE; // Toggle update register once + SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source again + + // Wait until the clock is updated + while (!(SCB_PLLCLKUEN & SCB_PLLCLKUEN_UPDATE)); + + // Set clock speed + switch (multiplier) + { + case CPU_MULTIPLIER_2: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_2 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_3: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_3 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_4: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_4 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_5: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_5 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_6: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_6 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + case CPU_MULTIPLIER_1: + default: + SCB_PLLCTRL = (SCB_PLLCTRL_MULT_1 | (1 << SCB_PLLCTRL_DIV_BIT)); + break; + } + + // Enable system PLL + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSPLL_MASK); + + // Wait for PLL to lock + while (!(SCB_PLLSTAT & SCB_PLLSTAT_LOCK)); + + // Setup main clock (use PLL output) + SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT; + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source + SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; + + // Wait until the clock is updated + while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE)); + + // Disable USB clock by default (enabled in USB code) + SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPAD_PD); // Power-down USB PHY + SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPLL_PD); // Power-down USB PLL + + // Set system AHB clock + SCB_SYSAHBCLKDIV = SCB_SYSAHBCLKDIV_DIV1; + + // Enabled IOCON clock for I/O related peripherals + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_IOCON; +} + +/**************************************************************************/ +/*! + @brief Initialises the CPU, setting up the PLL, etc. +*/ +/**************************************************************************/ +void cpuInit (void) +{ + gpioInit(); + + // Set all GPIO pins to input by default + GPIO_GPIO0DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO1DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO2DIR &= ~(GPIO_IO_ALL); + GPIO_GPIO3DIR &= ~(GPIO_IO_ALL); + + // Setup PLL (etc.) + cpuPllSetup(CPU_MULTIPLIER_6); +} diff --git a/core/cpu/cpu.h b/core/cpu/cpu.h new file mode 100644 index 0000000..f2e12ac --- /dev/null +++ b/core/cpu/cpu.h @@ -0,0 +1,76 @@ +/**************************************************************************/ +/*! + @file cpu.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include "projectconfig.h" + +// Macro to initialise, reset and enable the cycle counter. +// This can be used for rough timing and performance tests +// by resetting the cycle counter before a function, and +// then reading the value after with "int count = DWT_CYCCNT" +// +// CPU_RESET_CYCLECOUNTER; +// ... do something +// int count = DWT_CYCCNT; +// +#define CPU_RESET_CYCLECOUNTER do { SCB_DEMCR = SCB_DEMCR | 0x01000000; \ + DWT_CYCCNT = 0; \ + DWT_CTRL = DWT_CTRL | 1 ; } while(0) + +/**************************************************************************/ +/*! + @brief Indicates the value for the PLL multiplier +*/ +/**************************************************************************/ +typedef enum +{ + CPU_MULTIPLIER_1 = 0, + CPU_MULTIPLIER_2, + CPU_MULTIPLIER_3, + CPU_MULTIPLIER_4, + CPU_MULTIPLIER_5, + CPU_MULTIPLIER_6 +} +cpuMultiplier_t; + +void cpuPllSetup (cpuMultiplier_t multiplier); +void cpuInit (void); + +#endif \ No newline at end of file diff --git a/core/gpio/gpio.c b/core/gpio/gpio.c new file mode 100644 index 0000000..3809a5e --- /dev/null +++ b/core/gpio/gpio.c @@ -0,0 +1,550 @@ +/**************************************************************************/ +/*! + @file gpio.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the general purpose digital IO. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "gpio.h" + +#ifdef CFG_CHIBI +#include "drivers/chibi/chb_drvr.h" +volatile uint32_t chibi_counter = 0; +#endif + +static bool _gpioInitialised = false; + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 0 (currently checks pin 0.1) +*/ +/**************************************************************************/ +void PIOINT0_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(0, 1); + if (regVal) + { + gpioIntClear(0, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 1 (currently checks pin 1.1) +*/ +/**************************************************************************/ +void PIOINT1_IRQHandler(void) +{ + uint32_t regVal; + +#ifdef CFG_CHIBI + // Check for interrupt on 1.8 + regVal = gpioIntStatus(1, 8); + if (regVal) + { + chibi_counter++; + chb_ISR_Handler(); + gpioIntClear(1, 8); + } +#else + regVal = gpioIntStatus(1, 1); + if ( regVal ) + { + gpioIntClear(1, 1); + } +#endif + + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 2 (currently checks pin 2.1) +*/ +/**************************************************************************/ +void PIOINT2_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(2, 1); + if ( regVal ) + { + gpioIntClear(2, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief IRQ Handler for GPIO port 3 (currently checks pin 3.1) +*/ +/**************************************************************************/ +void PIOINT3_IRQHandler(void) +{ + uint32_t regVal; + + regVal = gpioIntStatus(3, 1); + if ( regVal ) + { + gpioIntClear(3, 1); + } + return; +} + +/**************************************************************************/ +/*! + @brief Initialises GPIO and enables the GPIO interrupt + handler for all GPIO ports. +*/ +/**************************************************************************/ +void gpioInit (void) +{ + /* Enable AHB clock to the GPIO domain. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_GPIO); + + /* Set up NVIC when I/O pins are configured as external interrupts. */ + NVIC_EnableIRQ(EINT0_IRQn); + NVIC_EnableIRQ(EINT1_IRQn); + NVIC_EnableIRQ(EINT2_IRQn); + NVIC_EnableIRQ(EINT3_IRQn); + + /* Set initialisation flag */ + _gpioInitialised = true; + + return; +} + +/**************************************************************************/ +/*! + @brief Sets the direction (input/output) for a specific port pin + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..11) + @param[in] dir + The pin direction (gpioDirection_Input or + gpioDirection_Output) +*/ +/**************************************************************************/ +void gpioSetDir (uint32_t portNum, uint32_t bitPos, gpioDirection_t dir) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiodir = &GPIO_GPIO0DIR; + switch (portNum) + { + case 0: + gpiodir = &GPIO_GPIO0DIR; + break; + case 1: + gpiodir = &GPIO_GPIO1DIR; + break; + case 2: + gpiodir = &GPIO_GPIO2DIR; + break; + case 3: + gpiodir = &GPIO_GPIO3DIR; + break; + } + + // Toggle dir + dir == gpioDirection_Output ? (*gpiodir |= (1 << bitPos)) : (*gpiodir &= ~(1 << bitPos)); +} + +/**************************************************************************/ +/*! + @brief Gets the value for a specific port pin + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + + @return The current value for the specified port pin (0..1) +*/ +/**************************************************************************/ +uint32_t gpioGetValue (uint32_t portNum, uint32_t bitPos) +{ + if (!_gpioInitialised) gpioInit(); + + uint32_t value = 0; + + switch (portNum) + { + case 0: + value = (GPIO_GPIO0DATA & (1 << bitPos)) ? 1 : 0; + break; + case 1: + value = (GPIO_GPIO1DATA & (1 << bitPos)) ? 1 : 0; + break; + case 2: + value = (GPIO_GPIO2DATA & (1 << bitPos)) ? 1 : 0; + break; + case 3: + value = (GPIO_GPIO3DATA & (1 << bitPos)) ? 1 : 0; + break; + default: + break; + } + + return value; +} + +/**************************************************************************/ +/*! + @brief Sets the value for a specific port pin (only relevant when a + pin is configured as output). + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + @param[in] bitValue + The value to set for the specified bit (0..1). 0 will set + the pin low and 1 will set the pin high. +*/ +/**************************************************************************/ +void gpioSetValue (uint32_t portNum, uint32_t bitPos, uint32_t bitVal) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiodata = &GPIO_GPIO0DATA; + switch (portNum) + { + case 0: + gpiodata = &GPIO_GPIO0DATA; + break; + case 1: + gpiodata = &GPIO_GPIO1DATA; + break; + case 2: + gpiodata = &GPIO_GPIO2DATA; + break; + case 3: + gpiodata = &GPIO_GPIO3DATA; + break; + } + + // Toggle value + bitVal == 1 ? (*gpiodata |= (1 << bitPos)) : (*gpiodata &= ~(1 << bitPos)); +} + +/**************************************************************************/ +/*! + @brief Sets the interrupt sense, event, etc. + + @param[in] portNum + The port number (0..3) + @param[in] bitPos + The bit position (0..31) + @param[in] sense + Whether the interrupt should be configured as edge or level + sensitive. + @param[in] edge + Whether one edge or both trigger an interrupt. + @param[in] event + Whether the rising or the falling edge (high or low) + should be used to trigger the interrupt. + + @section Example + + @code + // Initialise gpio + gpioInit(); + // Set GPIO1.8 to input + gpioSetDir(1, 8, gpioDirection_Input); + // Disable the internal pullup/down resistor on P1.8 + gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_Inactive); + // Setup an interrupt on GPIO1.8 + gpioSetInterrupt(1, // Port + 8, // Pin + gpioInterruptSense_Edge, // Edge/Level Sensitive + gpioInterruptEdge_Single, // Single/Double Edge + gpioInterruptEvent_ActiveHigh); // Rising/Falling + // Enable the interrupt + gpioIntEnable(1, 8); + @endcode +*/ +/**************************************************************************/ +void gpioSetInterrupt (uint32_t portNum, uint32_t bitPos, gpioInterruptSense_t sense, gpioInterruptEdge_t edge, gpioInterruptEvent_t event) +{ + if (!_gpioInitialised) gpioInit(); + + // Get the appropriate register (handled this way to optimise code size) + REG32 *gpiois = &GPIO_GPIO0IS; + REG32 *gpioibe = &GPIO_GPIO0IBE; + REG32 *gpioiev = &GPIO_GPIO0IEV; + switch (portNum) + { + case 0: + gpiois = &GPIO_GPIO0IS; + gpioibe = &GPIO_GPIO0IBE; + gpioiev = &GPIO_GPIO0IEV; + break; + case 1: + gpiois = &GPIO_GPIO1IS; + gpioibe = &GPIO_GPIO1IBE; + gpioiev = &GPIO_GPIO1IEV; + break; + case 2: + gpiois = &GPIO_GPIO2IS; + gpioibe = &GPIO_GPIO2IBE; + gpioiev = &GPIO_GPIO2IEV; + break; + case 3: + gpiois = &GPIO_GPIO3IS; + gpioibe = &GPIO_GPIO3IBE; + gpioiev = &GPIO_GPIO3IEV; + break; + } + + if (gpioInterruptSense_Edge) + { + *gpiois &= ~(0x1<= MAX_TIMEOUT); +} + +/***************************************************************************** +** Function name: I2CInit +** +** Descriptions: Initialize I2C controller +** +** parameters: I2c mode is either MASTER or SLAVE +** Returned value: true or false, return false if the I2C +** interrupt handler was not installed correctly +** +*****************************************************************************/ +uint32_t i2cInit( uint32_t I2cMode ) +{ + SCB_PRESETCTRL |= (0x1<<1); + + // Enable I2C clock + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_I2C); + + // Configure pin 0.4 for SCL + IOCON_PIO0_4 &= ~(IOCON_PIO0_4_FUNC_MASK | IOCON_PIO0_4_I2CMODE_MASK); + IOCON_PIO0_4 |= (IOCON_PIO0_4_FUNC_I2CSCL); + + // Configure pin 0.5 for SDA + IOCON_PIO0_5 &= ~(IOCON_PIO0_5_FUNC_MASK | IOCON_PIO0_5_I2CMODE_MASK); + IOCON_PIO0_5 |= IOCON_PIO0_5_FUNC_I2CSDA; + + // Clear flags + I2C_I2CCONCLR = I2C_I2CCONCLR_AAC | + I2C_I2CCONCLR_SIC | + I2C_I2CCONCLR_STAC | + I2C_I2CCONCLR_I2ENC; + + // See p.128 for appropriate values for SCLL and SCLH +#if I2C_FAST_MODE_PLUS + IOCON_PIO0_4 |= (IOCON_PIO0_4_I2CMODE_FASTPLUSI2C); + IOCON_PIO0_5 |= (IOCON_PIO0_5_I2CMODE_FASTPLUSI2C); + I2C_I2CSCLL = I2C_SCLL_HS_SCLL; + I2C_I2CSCLH = I2C_SCLH_HS_SCLH; +#else + I2C_I2CSCLL = I2SCLL_SCLL; + I2C_I2CSCLH = I2SCLH_SCLH; +#endif + + if ( I2cMode == I2CSLAVE ) + { + I2C_I2CADR0 = SLAVE_ADDR; + } + + /* Enable the I2C Interrupt */ + NVIC_EnableIRQ(I2C_IRQn); + I2C_I2CCONSET = I2C_I2CCONSET_I2EN; + + return( TRUE ); +} + +/***************************************************************************** +** Function name: I2CEngine +** +** Descriptions: The routine to complete a I2C transaction +** from start to stop. All the intermitten +** steps are handled in the interrupt handler. +** Before this routine is called, the read +** length, write length and I2C master buffer +** need to be filled. +** +** parameters: None +** Returned value: Any of the I2CSTATE_... values. See i2c.h +** +*****************************************************************************/ +uint32_t i2cEngine( void ) +{ + I2CMasterState = I2CSTATE_IDLE; + RdIndex = 0; + WrIndex = 0; + if ( I2CStart() != TRUE ) + { + I2CStop(); + return ( FALSE ); + } + + /* wait until the state is a terminal state */ + while (I2CMasterState < 0x100); + + return ( I2CMasterState ); +} + +/****************************************************************************** +** End Of File +******************************************************************************/ + diff --git a/core/i2c/i2c.h b/core/i2c/i2c.h new file mode 100644 index 0000000..9ed49be --- /dev/null +++ b/core/i2c/i2c.h @@ -0,0 +1,83 @@ +/***************************************************************************** + * i2c.h: Header file for NXP LPC11xx Family Microprocessors + * + * Copyright(C) 2006, NXP Semiconductor + * Parts of this code are (C) 2010, MyVoice CAD/CAM Services + * All rights reserved. + * + * History + * 2006.07.19 ver 1.00 Preliminary version, first Release + * 2010.07.19 ver 1.10 Rob Jansen - MyVoice CAD/CAM Services + * Updated to reflect new code + * +******************************************************************************/ +#ifndef __I2C_H +#define __I2C_H + +#include "projectconfig.h" + +/* + * These are states returned by the I2CEngine: + * + * IDLE - is never returned but only used internally + * PENDING - is never returned but only used internally in the I2C functions + * ACK - The transaction finished and the slave returned ACK (on all bytes) + * NACK - The transaction is aborted since the slave returned a NACK + * SLA_NACK - The transaction is aborted since the slave returned a NACK on the SLA + * this can be intentional (e.g. an 24LC08 EEPROM states it is busy) + * or the slave is not available/accessible at all. + * ARB_LOSS - Arbitration loss during any part of the transaction. + * This could only happen in a multi master system or could also + * identify a hardware problem in the system. + */ +#define I2CSTATE_IDLE 0x000 +#define I2CSTATE_PENDING 0x001 +#define I2CSTATE_ACK 0x101 +#define I2CSTATE_NACK 0x102 +#define I2CSTATE_SLA_NACK 0x103 +#define I2CSTATE_ARB_LOSS 0x104 + +#define FAST_MODE_PLUS 0 + +#define I2C_BUFSIZE 6 +#define MAX_TIMEOUT 0x00FFFFFF + +#define I2CMASTER 0x01 +#define I2CSLAVE 0x02 + +#define SLAVE_ADDR 0xA0 +#define READ_WRITE 0x01 + +#define RD_BIT 0x01 + +#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */ +#define I2CONSET_AA 0x00000004 +#define I2CONSET_SI 0x00000008 +#define I2CONSET_STO 0x00000010 +#define I2CONSET_STA 0x00000020 + +#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */ +#define I2CONCLR_SIC 0x00000008 +#define I2CONCLR_STAC 0x00000020 +#define I2CONCLR_I2ENC 0x00000040 + +#define I2DAT_I2C 0x00000000 /* I2C Data Reg */ +#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */ +#define I2SCLH_SCLH 120 /* I2C SCL Duty Cycle High Reg */ +#define I2SCLL_SCLL 120 /* I2C SCL Duty Cycle Low Reg */ +#define I2SCLH_HS_SCLH 0x00000020 /* Fast Plus I2C SCL Duty Cycle High Reg */ +#define I2SCLL_HS_SCLL 0x00000020 /* Fast Plus I2C SCL Duty Cycle Low Reg */ + + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +extern void I2C_IRQHandler( void ); +extern uint32_t i2cInit( uint32_t I2cMode ); +extern uint32_t i2cEngine( void ); + +#endif /* end __I2C_H */ +/**************************************************************************** +** End Of File +*****************************************************************************/ diff --git a/core/iap/iap.c b/core/iap/iap.c new file mode 100644 index 0000000..dba85b1 --- /dev/null +++ b/core/iap/iap.c @@ -0,0 +1,57 @@ +/**************************************************************************/ +/*! + @file iap.c + Source: http://knowledgebase.nxp.com/showthread.php?t=1594 +*/ +/**************************************************************************/ +#include "iap.h" + +IAP_return_t iap_return; + +#define IAP_ADDRESS 0x1FFF1FF1 +uint32_t param_table[5]; + +/**************************************************************************/ +/*! + Sends the IAP command and stores the result +*/ +/**************************************************************************/ +void iap_entry(uint32_t param_tab[], uint32_t result_tab[]) +{ + void (*iap)(uint32_t[], uint32_t[]); + iap = (void (*)(uint32_t[], uint32_t[]))IAP_ADDRESS; + iap(param_tab,result_tab); +} + +/**************************************************************************/ +/*! + Returns the CPU's unique 128-bit serial number (4 words long) + + @section Example + + @code + #include "core/iap/iap.h" + + IAP_return_t iap_return; + iap_return = iapReadSerialNumber(); + + if (iap_return.ReturnCode == 0) + { + printf("Serial Number: %08X %08X %08X %08X %s", + iap_return.Result[0], + iap_return.Result[1], + iap_return.Result[2], + iap_return.Result[3], + CFG_PRINTF_NEWLINE); + } + @endcode +*/ +/**************************************************************************/ +IAP_return_t iapReadSerialNumber(void) +{ + // ToDo: Why does IAP sometime cause the application to halt when read??? + param_table[0] = IAP_CMD_READUID; + iap_entry(param_table,(uint32_t*)(&iap_return)); + return iap_return; +} + diff --git a/core/iap/iap.h b/core/iap/iap.h new file mode 100644 index 0000000..7bc643e --- /dev/null +++ b/core/iap/iap.h @@ -0,0 +1,60 @@ +/**************************************************************************/ +/*! + @file iap.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _IAP_H_ +#define _IAP_H_ + +#include "projectconfig.h" + +#define IAP_CMD_PREPARESECTORFORWRITE (50) +#define IAP_CMD_COPYRAMTOFLASH (51) +#define CAP_CMD_ERASESECTORS (52) +#define IAP_CMD_BLANKCHECKSECTOR (53) +#define IAP_CMD_READPARTID (54) +#define IAP_CMD_READBOOTCODEVERSION (55) +#define IAP_CMD_COMPARE (56) +#define IAP_CMD_REINVOKEISP (57) +#define IAP_CMD_READUID (58) + +typedef struct +{ + unsigned int ReturnCode; + unsigned int Result[4]; +} IAP_return_t; + +IAP_return_t iapReadSerialNumber(void); + +#endif \ No newline at end of file diff --git a/core/libc/ctype.c b/core/libc/ctype.c new file mode 100644 index 0000000..086065e --- /dev/null +++ b/core/libc/ctype.c @@ -0,0 +1,104 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Uwe Hermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + * SUCH DAMAGE. + */ + +int isalpha(int c) +{ + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} + +int isascii(int c) +{ + return (c >= 0 && c <= 127); +} + +int isblank(int c) +{ + return (c == ' ' || c == '\t'); +} + +int iscntrl(int c) +{ + return (c <= 31 || c == 127); +} + +int isdigit(int c) +{ + return (c >= '0' && c <= '9'); +} + +int isalnum(int c) +{ + return isalpha(c) || isdigit(c); +} + +int isgraph(int c) +{ + return (c >= 33 && c <= 126); +} + +int islower(int c) +{ + return (c >= 'a' && c <= 'z'); +} + +int isprint(int c) +{ + return (c >= 32 && c <= 126); +} + + +int isspace(int c) +{ + return (c == ' ' || (c >= '\t' || c <= '\r')); +} + +int isupper(int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +int tolower(int c) +{ + return (c >= 'A' && c <= 'Z') ? (c + 32) : c; +} + +int toupper(int c) +{ + return (c >= 'a' && c <= 'z') ? (c - 32) : c; +} + +int isxdigit(int c) +{ + return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'z'); +} + +int ispunct(int c) +{ + return isprint(c) && !isspace(c) && !isalnum(c); +} diff --git a/core/libc/stdio.c b/core/libc/stdio.c new file mode 100644 index 0000000..84d7db8 --- /dev/null +++ b/core/libc/stdio.c @@ -0,0 +1,475 @@ +/* + * Software License Agreement (BSD License) + * + * Based on original stdio.c released by Atmel + * Copyright (c) 2008, Atmel Corporation + * All rights reserved. + * + * Modified by Roel Verdult, Copyright (c) 2010 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include + +//------------------------------------------------------------------------------ +// Local Definitions +//------------------------------------------------------------------------------ + +// Maximum string size allowed (in bytes). +#define MAX_STRING_SIZE 255 + +//------------------------------------------------------------------------------ +// Global Variables +//------------------------------------------------------------------------------ + +// Required for proper compilation. +//struct _reent r = {0, (FILE*) 0, (FILE*) 1, (FILE*) 0}; +//struct _reent *_impure_ptr = &r; + +//------------------------------------------------------------------------------ +// Local Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Writes a character inside the given string. Returns 1. +// \param pStr Storage string. +// \param c Character to write. +//------------------------------------------------------------------------------ +signed int append_char(char *pStr, char c) +{ + *pStr = c; + return 1; +} + +//------------------------------------------------------------------------------ +// Writes a string inside the given string. +// Returns the size of the written +// string. +// \param pStr Storage string. +// \param pSource Source string. +//------------------------------------------------------------------------------ +signed int PutString(char *pStr, char fill, signed int width, const char *pSource) +{ + signed int num = 0; + + while (*pSource != 0) { + + *pStr++ = *pSource++; + num++; + } + + width -= num; + while (width > 0) { + + *pStr++ = fill; + num++; + width--; + } + + return num; +} + +//------------------------------------------------------------------------------ +// Writes an unsigned int inside the given string, using the provided fill & +// width parameters. +// Returns the size in characters of the written integer. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param value Integer value. +//------------------------------------------------------------------------------ +signed int PutUnsignedInt( + char *pStr, + char fill, + signed int width, + unsigned int value) +{ + signed int num = 0; + + // Take current digit into account when calculating width + width--; + + // Recursively write upper digits + if ((value / 10) > 0) { + + num = PutUnsignedInt(pStr, fill, width, value / 10); + pStr += num; + } + // Write filler characters + else { + + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + } + + // Write lower digit + num += append_char(pStr, (value % 10) + '0'); + + return num; +} + +//------------------------------------------------------------------------------ +// Writes a signed int inside the given string, using the provided fill & width +// parameters. +// Returns the size of the written integer. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param value Signed integer value. +//------------------------------------------------------------------------------ +signed int PutSignedInt( + char *pStr, + char fill, + signed int width, + signed int value) +{ + signed int num = 0; + unsigned int absolute; + + // Compute absolute value + if (value < 0) { + + absolute = -value; + } + else { + + absolute = value; + } + + // Take current digit into account when calculating width + width--; + + // Recursively write upper digits + if ((absolute / 10) > 0) { + + if (value < 0) { + + num = PutSignedInt(pStr, fill, width, -(absolute / 10)); + } + else { + + num = PutSignedInt(pStr, fill, width, absolute / 10); + } + pStr += num; + } + else { + + // Reserve space for sign + if (value < 0) { + + width--; + } + + // Write filler characters + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + + // Write sign + if (value < 0) { + + num += append_char(pStr, '-'); + pStr++; + } + } + + // Write lower digit + num += append_char(pStr, (absolute % 10) + '0'); + + return num; +} + +//------------------------------------------------------------------------------ +// Writes an hexadecimal value into a string, using the given fill, width & +// capital parameters. +// Returns the number of char written. +// \param pStr Storage string. +// \param fill Fill character. +// \param width Minimum integer width. +// \param maj Indicates if the letters must be printed in lower- or upper-case. +// \param value Hexadecimal value. +//------------------------------------------------------------------------------ +signed int PutHexa( + char *pStr, + char fill, + signed int width, + unsigned char maj, + unsigned int value) +{ + signed int num = 0; + + // Decrement width + width--; + + // Recursively output upper digits + if ((value >> 4) > 0) { + + num += PutHexa(pStr, fill, width, maj, value >> 4); + pStr += num; + } + // Write filler chars + else { + + while (width > 0) { + + append_char(pStr, fill); + pStr++; + num++; + width--; + } + } + + // Write current digit + if ((value & 0xF) < 10) { + + append_char(pStr, (value & 0xF) + '0'); + } + else if (maj) { + + append_char(pStr, (value & 0xF) - 10 + 'A'); + } + else { + + append_char(pStr, (value & 0xF) - 10 + 'a'); + } + num++; + + return num; +} + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pStr Destination string. +/// \param length Length of Destination string. +/// \param pFormat Format string. +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap) +{ + char fill; + unsigned char width; + signed int num = 0; + signed int size = 0; + + // Clear the string + if (pStr) { + + *pStr = 0; + } + + // Phase string + while (*pFormat != 0 && size < length) { + + // Normal character + if (*pFormat != '%') { + + *pStr++ = *pFormat++; + size++; + } + // Escaped '%' + else if (*(pFormat+1) == '%') { + + *pStr++ = '%'; + pFormat += 2; + size++; + } + // Token delimiter + else { + + fill = ' '; + width = 0; + pFormat++; + + // Parse filler + if (*pFormat == '0') { + + fill = '0'; + pFormat++; + } + + // Ignore justifier + if (*pFormat == '-') { + pFormat++; + } + + // Parse width + while ((*pFormat >= '0') && (*pFormat <= '9')) { + + width = (width*10) + *pFormat-'0'; + pFormat++; + } + + // Check if there is enough space + if (size + width > length) { + + width = length - size; + } + + // Parse type + switch (*pFormat) { + case 'd': + case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break; + case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break; + case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break; + case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break; + case 's': num = PutString(pStr, fill, width, va_arg(ap, char *)); break; + case 'c': num = append_char(pStr, va_arg(ap, unsigned int)); break; + default: + return EOF; + } + + pFormat++; + pStr += num; + size += num; + } + } + + // NULL-terminated (final \0 is not counted) + if (size < length) { + + *pStr = 0; + } + else { + + *(--pStr) = 0; + size--; + } + + return size; +} + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pString Destination string. +/// \param length Length of Destination string. +/// \param pFormat Format string. +/// \param ... Other arguments +//------------------------------------------------------------------------------ +signed int snprintf(char *pString, size_t length, const char *pFormat, ...) +{ + va_list ap; + signed int rc; + + va_start(ap, pFormat); + rc = vsnprintf(pString, length, pFormat, ap); + va_end(ap); + + return rc; +} + +//------------------------------------------------------------------------------ +/// Stores the result of a formatted string into another string. Format +/// arguments are given in a va_list instance. +/// Return the number of characters written. +/// \param pString Destination string. +/// \param pFormat Format string. +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vsprintf(char *pString, const char *pFormat, va_list ap) +{ + return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap); +} + +//------------------------------------------------------------------------------ +/// Outputs a formatted string on the DBGU stream. Format arguments are given +/// in a va_list instance. +/// \param pFormat Format string +/// \param ap Argument list. +//------------------------------------------------------------------------------ +signed int vprintf(const char *pFormat, va_list ap) +{ + char pStr[MAX_STRING_SIZE]; + char pError[] = "stdio.c: increase MAX_STRING_SIZE\r\n"; + + // Write formatted string in buffer + if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) { + + puts(pError); + while (1); // Increase MAX_STRING_SIZE + } + + // Display string + return puts(pStr); +} + +//------------------------------------------------------------------------------ +/// Outputs a formatted string on the DBGU stream, using a variable number of +/// arguments. +/// \param pFormat Format string. +//------------------------------------------------------------------------------ +signed int printf(const char *pFormat, ...) +{ + va_list ap; + signed int result; + + // Forward call to vprintf + va_start(ap, pFormat); + result = vprintf(pFormat, ap); + va_end(ap); + + return result; +} + + +//------------------------------------------------------------------------------ +/// Writes a formatted string inside another string. +/// \param pStr Storage string. +/// \param pFormat Format string. +//------------------------------------------------------------------------------ +signed int sprintf(char *pStr, const char *pFormat, ...) +{ + va_list ap; + signed int result; + + // Forward call to vsprintf + va_start(ap, pFormat); + result = vsprintf(pStr, pFormat, ap); + va_end(ap); + + return result; +} \ No newline at end of file diff --git a/core/libc/string.c b/core/libc/string.c new file mode 100644 index 0000000..3216009 --- /dev/null +++ b/core/libc/string.c @@ -0,0 +1,328 @@ +/* + * Software License Agreement (BSD License) + * + * Based on original stdio.c released by Atmel + * Copyright (c) 2008, Atmel Corporation + * All rights reserved. + * + * Modified by Roel Verdult, Copyright (c) 2010 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Copies data from a source buffer into a destination buffer. The two buffers +/// must NOT overlap. Returns the destination buffer. +/// \param pDestination Destination buffer. +/// \param pSource Source buffer. +/// \param num Number of bytes to copy. +//------------------------------------------------------------------------------ +void * memcpy(void *pDestination, const void *pSource, size_t num) +{ + unsigned char *pByteDestination; + unsigned char *pByteSource; + unsigned int *pAlignedSource = (unsigned int *) pSource; + unsigned int *pAlignedDestination = (unsigned int *) pDestination; + + // If num is more than 4 bytes, and both dest. and source are aligned, + // then copy dwords + if ((((unsigned int) pAlignedDestination & 0x3) == 0) + && (((unsigned int) pAlignedSource & 0x3) == 0) + && (num >= 4)) { + + while (num >= 4) { + + *pAlignedDestination++ = *pAlignedSource++; + num -= 4; + } + } + + // Copy remaining bytes + pByteDestination = (unsigned char *) pAlignedDestination; + pByteSource = (unsigned char *) pAlignedSource; + while (num--) { + + *pByteDestination++ = *pByteSource++; + } + + return pDestination; +} + +//------------------------------------------------------------------------------ +/// Fills a memory region with the given value. Returns a pointer to the +/// memory region. +/// \param pBuffer Pointer to the start of the memory region to fill +/// \param value Value to fill the region with +/// \param num Size to fill in bytes +//------------------------------------------------------------------------------ +void * memset(void *pBuffer, int value, size_t num) +{ + unsigned char *pByteDestination; + unsigned int *pAlignedDestination = (unsigned int *) pBuffer; + unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value; + + // Set words if possible + if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) { + while (num >= 4) { + *pAlignedDestination++ = alignedValue; + num -= 4; + } + } + // Set remaining bytes + pByteDestination = (unsigned char *) pAlignedDestination; + while (num--) { + *pByteDestination++ = value; + } + return pBuffer; +} + +void* memmove(void *s1, const void *s2, size_t n) +{ + char *s=(char*)s2, *d=(char*)s1; + + if(d > s){ + s+=n-1; + d+=n-1; + while(n){ + *d--=*s--; + n--; + } + }else if(d < s) + while(n){ + *d++=*s++; + n--; + } + return s1; +} + +int memcmp(const void *av, const void *bv, size_t len) +{ + const unsigned char *a = av; + const unsigned char *b = bv; + size_t i; + + for (i=0; i0 if 1st string > 2nd string +/// Return <0 if 1st string < 2nd string +/// \param pString1 Pointer to the start of the 1st string. +/// \param pString2 Pointer to the start of the 2nd string. +/// \param count Number of bytes that should be compared. +//----------------------------------------------------------------------------- +int strncmp(const char *pString1, const char *pString2, size_t count) +{ + int r; + + while(count) { + r = *pString1 - *pString2; + if (r == 0) { + if (*pString1 == 0) { + break; + } + pString1++; + pString2++; + count--; + continue; + } + return r; + } + return 0; +} + +//----------------------------------------------------------------------------- +/// Copy the first number of bytes from source string to destination string +/// Return the pointer to the destination string. +/// \param pDestination Pointer to the start of destination string. +/// \param pSource Pointer to the start of the source string. +/// \param count Number of bytes that should be copied. +//----------------------------------------------------------------------------- +char * strncpy(char *pDestination, const char *pSource, size_t count) +{ + char *pSaveDest = pDestination; + + while (count) { + *pDestination = *pSource; + if (*pSource == 0) { + break; + } + pDestination++; + pSource++; + count--; + } + return pSaveDest; +} + +// Following code is based on the BSD licensed code released by UoC +// Copyright (c) 1988 Regents of the University of California + +int strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + return (*(unsigned char *)s1 - *(unsigned char *)--s2); +} + +char *strtok(char *s, const char *delim) +{ + static char *last; + return strtok_r(s, delim, &last); +} + +char *strtok_r(char *s, const char *delim, char **last) +{ + char *spanp; + int c, sc; + char *tok; + + + if (s == NULL && (s = *last) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *last = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} diff --git a/core/pmu/pmu.c b/core/pmu/pmu.c new file mode 100644 index 0000000..d90d228 --- /dev/null +++ b/core/pmu/pmu.c @@ -0,0 +1,419 @@ +/**************************************************************************/ +/*! + @file pmu.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the power management features of the LPC1343, allowing you + to enter sleep/deep-sleep or deep power-down mode. + + For examples of how to enter either mode, see the comments for the + functions pmuSleep(), pmuDeepSleep() and pmuPowerDown(). + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "core/gpio/gpio.h" +#include "core/cpu/cpu.h" +#include "core/timer32/timer32.h" +#include "pmu.h" + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb_drvr.h" +#endif +#define PMU_WDTCLOCKSPEED_HZ 7812 + +void pmuSetupHW(void); +void pmuRestoreHW(void); + + +/**************************************************************************/ +/*! + Wakeup interrupt handler +*/ +/**************************************************************************/ +void WAKEUP_IRQHandler(void) +{ + uint32_t regVal; + + // Reconfigure system clock/PLL + cpuPllSetup(CPU_MULTIPLIER_6); + + // Clear match bit on timer + TMR_TMR32B0EMR = 0; + + // Clear pending bits + SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK; + + // Clear SLEEPDEEP bit + SCB_SCR &= ~SCB_SCR_SLEEPDEEP; + + // Disable the deep sleep timer + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + + /* This handler takes care of all the port pins if they + are configured as wakeup source. */ + regVal = SCB_STARTSRP0; + if (regVal != 0) + { + SCB_STARTRSRP0CLR = regVal; + } + + // Reconfigure CT32B0 + timer32Init(0, TIMER32_DEFAULTINTERVAL); + timer32Enable(0); + + // Perform peripheral specific and custom wakeup tasks + pmuRestoreHW(); + + /* See tracker for bug report. */ + __asm volatile ("NOP"); + + return; +} + +/**************************************************************************/ +/*! + Setup the clock for the watchdog timer. The default is 7.8125kHz. +*/ +/**************************************************************************/ +static void pmuWDTClockInit (void) +{ + /* Enable WDT clock */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC); + + /* Configure watchdog clock */ + /* Freq. = 0.5MHz, div = 64: WDT_OSC = 7.8125kHz */ + SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ | + SCB_WDTOSCCTRL_DIVSEL_DIV64; + + // Switch main clock to WDT output + SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_WDTOSC; + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source + SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once + SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; + + // Wait until the clock is updated + while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE)); +} + +/**************************************************************************/ +/*! + @brief Initialises the power management unit +*/ +/**************************************************************************/ +void pmuInit( void ) +{ + /* Enable all clocks, even those turned off at power up. */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC_MASK | + SCB_PDRUNCFG_SYSOSC_MASK | + SCB_PDRUNCFG_ADC_MASK); + + return; +} + +/**************************************************************************/ +/*! + @brief Puts select peripherals in sleep mode. + + This function will put the device into sleep mode. Most gpio pins + can be used to wake the device up, but the pins must first be + configured for this in pmuInit. + + @section Example + + @code + // Configure wakeup sources before going into sleep/deep-sleep. + // By default, pin 0.1 is configured as wakeup source (falling edge) + pmuInit(); + + // Enter sleep mode + pmuSleep(); + @endcode +*/ +/**************************************************************************/ +void pmuSleep() +{ + SCB_PDAWAKECFG = SCB_PDRUNCFG; + __asm volatile ("WFI"); + return; +} + +/**************************************************************************/ +/*! + @brief Turns off select peripherals and puts the device in deep-sleep + mode. + + The device can be configured to wakeup from deep-sleep mode after a + specified delay by supplying a non-zero value to the wakeupSeconds + parameter. This will configure CT32B0 to toggle pin 0.1 (CT32B0_MAT2) + after x seconds, waking the device up. The timer will be configured + to run off the WDT OSC while in deep-sleep mode, meaning that WDTOSC + should not be powered off (using the sleepCtrl parameter) when a + wakeup delay is specified. + + The sleepCtrl parameter is used to indicate which peripherals should + be put in sleep mode (see the SCB_PDSLEEPCFG register for details). + + @param[in] sleepCtrl + The bits to set in the SCB_PDSLEEPCFG register. This + controls which peripherals will be put in sleep mode. + @param[in] wakeupSeconds + The number of seconds to wait until the device will + wakeup. If you do not wish to wakeup after a specific + delay, enter a value of 0. + + @code + uint32_t pmuRegVal; + + // Initialise power management unit + pmuInit(); + + // Put peripherals into sleep mode + pmuRegVal = SCB_PDSLEEPCFG_IRCOUT_PD | + SCB_PDSLEEPCFG_IRC_PD | + SCB_PDSLEEPCFG_FLASH_PD | + SCB_PDSLEEPCFG_USBPLL_PD | + SCB_PDSLEEPCFG_SYSPLL_PD | + SCB_PDSLEEPCFG_SYSOSC_PD | + SCB_PDSLEEPCFG_ADC_PD | + SCB_PDSLEEPCFG_BOD_PD; + + // Enter deep sleep mode (wakeup after 5 seconds) + // By default, pin 0.1 is configured as wakeup source + pmuDeepSleep(pmuRegVal, 5); + @endcode +*/ +/**************************************************************************/ +void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds) +{ + // Setup the board for deep sleep mode, shutting down certain + // peripherals and remapping pins for lower power + pmuSetupHW(); + SCB_PDAWAKECFG = SCB_PDRUNCFG; + sleepCtrl |= (1 << 9) | (1 << 11); + SCB_PDSLEEPCFG = sleepCtrl; + SCB_SCR |= SCB_SCR_SLEEPDEEP; + + /* Configure system to run from WDT and set TMR32B0 for wakeup */ + if (wakeupSeconds > 0) + { + // Make sure WDTOSC isn't disabled in PDSLEEPCFG + SCB_PDSLEEPCFG &= ~(SCB_PDSLEEPCFG_WDTOSC_PD); + + // Disable 32-bit timer 0 if currently in use + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + + // Disable internal pullup on 0.1 + gpioSetPullup(&IOCON_PIO0_1, gpioPullupMode_Inactive); + + /* Enable the clock for CT32B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); + + /* Configure 0.1 as Timer0_32 MAT2 */ + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2; + + /* Set appropriate timer delay */ + TMR_TMR32B0MR0 = PMU_WDTCLOCKSPEED_HZ * wakeupSeconds; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B0MCR |= (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED); + + /* Configure external match register to set 0.1 high on match */ + TMR_TMR32B0EMR &= ~(0xFF<<4); // Clear EMR config bits + TMR_TMR32B0EMR |= TMR_TMR32B0EMR_EMC2_HIGH; // Set MAT2 (0.1) high on match + + /* Enable wakeup interrupts (any I/O pin can be used as a wakeup source) */ + //NVIC_EnableIRQ(WAKEUP0_IRQn); // P0.0 + NVIC_EnableIRQ(WAKEUP1_IRQn); // P0.1 (CT32B0_MAT2) + //NVIC_EnableIRQ(WAKEUP2_IRQn); // P0.2 + //NVIC_EnableIRQ(WAKEUP3_IRQn); // P0.3 + //NVIC_EnableIRQ(WAKEUP4_IRQn); // P0.4 + //NVIC_EnableIRQ(WAKEUP5_IRQn); // P0.5 + //NVIC_EnableIRQ(WAKEUP6_IRQn); // P0.6 + //NVIC_EnableIRQ(WAKEUP7_IRQn); // P0.7 + //NVIC_EnableIRQ(WAKEUP8_IRQn); // P0.8 + //NVIC_EnableIRQ(WAKEUP9_IRQn); // P0.9 + //NVIC_EnableIRQ(WAKEUP10_IRQn); // P0.10 + //NVIC_EnableIRQ(WAKEUP11_IRQn); // P0.11 + //NVIC_EnableIRQ(WAKEUP12_IRQn); // P1.0 + //NVIC_EnableIRQ(WAKEUP13_IRQn); // P1.1 + //NVIC_EnableIRQ(WAKEUP14_IRQn); // P1.2 + //NVIC_EnableIRQ(WAKEUP15_IRQn); // P1.3 + //NVIC_EnableIRQ(WAKEUP16_IRQn); // P1.4 + //NVIC_EnableIRQ(WAKEUP17_IRQn); // P1.5 + //NVIC_EnableIRQ(WAKEUP18_IRQn); // P1.6 + //NVIC_EnableIRQ(WAKEUP19_IRQn); // P1.7 + //NVIC_EnableIRQ(WAKEUP20_IRQn); // P1.8 + //NVIC_EnableIRQ(WAKEUP21_IRQn); // P1.9 + //NVIC_EnableIRQ(WAKEUP22_IRQn); // P1.10 + //NVIC_EnableIRQ(WAKEUP23_IRQn); // P1.11 + //NVIC_EnableIRQ(WAKEUP24_IRQn); // P2.0 + //NVIC_EnableIRQ(WAKEUP25_IRQn); // P2.1 + //NVIC_EnableIRQ(WAKEUP26_IRQn); // P2.2 + //NVIC_EnableIRQ(WAKEUP27_IRQn); // P2.3 + //NVIC_EnableIRQ(WAKEUP28_IRQn); // P2.4 + //NVIC_EnableIRQ(WAKEUP29_IRQn); // P2.5 + //NVIC_EnableIRQ(WAKEUP30_IRQn); // P2.6 + //NVIC_EnableIRQ(WAKEUP31_IRQn); // P2.7 + //NVIC_EnableIRQ(WAKEUP32_IRQn); // P2.8 + //NVIC_EnableIRQ(WAKEUP33_IRQn); // P2.9 + //NVIC_EnableIRQ(WAKEUP34_IRQn); // P2.10 + //NVIC_EnableIRQ(WAKEUP35_IRQn); // P2.11 + //NVIC_EnableIRQ(WAKEUP36_IRQn); // P3.0 + //NVIC_EnableIRQ(WAKEUP37_IRQn); // P3.1 + //NVIC_EnableIRQ(WAKEUP38_IRQn); // P3.2 + //NVIC_EnableIRQ(WAKEUP39_IRQn); // P3.3 + + /* Use RISING EDGE for wakeup detection. */ + SCB_STARTAPRP0 |= SCB_STARTAPRP0_APRPIO0_1; + + /* Clear all wakeup sources */ + SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK; + + /* Enable Port 0.1 as wakeup source. */ + SCB_STARTERP0 |= SCB_STARTERP0_ERPIO0_1; + + // Reconfigure clock to run from WDTOSC + pmuWDTClockInit(); + + /* Start the timer */ + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED; + } + + __asm volatile ("WFI"); + return; +} + +/**************************************************************************/ +/*! + @brief Puts the device in deep power-down mode. + + This function will configure the PMU control register and enter + deep power-down mode. Pre-determined values are stored in the four + general-purpose registers (PMU_GPREG0..3), which can be used to persist + any essential system settings while the device is in deep power-down + mode, so long as 3.3V is still available. + + @warning The only way to wake a device up from deep power-down mode + is to set a low-level on P1.4. If 3.3V power is lost, the + values stored in the four general-purpose registers will + also be lost. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/pmu/pmu.h" + + int main(void) + { + cpuInit(); + pmuInit(); + + // Enter power-down mode + pmuPowerDown(); + + while(1) + { + // Device was woken up by WAKEUP pin + } + } + @endcode +*/ +/**************************************************************************/ +void pmuPowerDown( void ) +{ + uint32_t regVal; + + // Make sure HW and external devices are in low power mode + pmuSetupHW(); + + if ( (PMU_PMUCTRL & ((0x1<<8) | (PMU_PMUCTRL_DPDFLAG))) != 0x0 ) + { + /* Check sleep and deep power down bits. If sleep and/or + deep power down mode are entered, clear the PCON bits. */ + regVal = PMU_PMUCTRL; + regVal |= ((0x1<<8) | + (PMU_PMUCTRL_DPDEN_SLEEP) | + (PMU_PMUCTRL_DPDFLAG)); + PMU_PMUCTRL = regVal; + + if ( (PMU_GPREG0 != 0x12345678)||(PMU_GPREG1 != 0x87654321) + ||(PMU_GPREG2 != 0x56781234)||(PMU_GPREG3 != 0x43218765) ) + { + while (1); + } + } + else + { + /* If in neither sleep nor deep-sleep mode, enter deep power down mode. */ + PMU_GPREG0 = 0x12345678; + PMU_GPREG1 = 0x87654321; + PMU_GPREG2 = 0x56781234; + PMU_GPREG3 = 0x43218765; + SCB_SCR |= SCB_SCR_SLEEPDEEP; + PMU_PMUCTRL = PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN; + __asm volatile ("WFI"); + } + return; +} + +/**************************************************************************/ +/*! + @brief Configures parts and system peripherals to use lower power + before entering sleep mode +*/ +/**************************************************************************/ +void pmuSetupHW(void) +{ + #ifdef CFG_CHIBI + chb_sleep(TRUE); + #endif +} + +/**************************************************************************/ +/*! + @brief Restores parts and system peripherals to an appropriate + state after waking up from deep-sleep mode +*/ +/**************************************************************************/ +void pmuRestoreHW(void) +{ + #ifdef CFG_CHIBI + // Wakeup Chibi/Transceiver + chb_sleep(FALSE); + #endif +} diff --git a/core/pmu/pmu.h b/core/pmu/pmu.h new file mode 100644 index 0000000..58504e6 --- /dev/null +++ b/core/pmu/pmu.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file pmu.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __PMU_H__ +#define __PMU_H__ + +#include "projectconfig.h" + +void WAKEUP_IRQHandler( void ); +void pmuInit( void ); +void pmuSleep( void ); +void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds); +void pmuPowerDown( void ); + +#endif diff --git a/core/pwm/pwm.c b/core/pwm/pwm.c new file mode 100644 index 0000000..b94329f --- /dev/null +++ b/core/pwm/pwm.c @@ -0,0 +1,254 @@ +/**************************************************************************/ +/*! + @file pwm.c + @author K. Townsend (microBuilder.eu) + + @brief Simple PWM example that can be used to control a motor, dim + an LED, etc. Uses 16-bit Timer 1 and P1.9 for PWM output. + + @section Example + + @code + #include "core/pwm/pwm.h" + ... + + // Initialises PWM output on 16-bit Timer 1 and + // sets MAT0 (P1.9) as output + pwmInit(); + + // Setup the pulse-width and duty-cycle + pwmSetDutyCycle(50); // Set 50% duty cycle + pwmSetFrequencyInMicroseconds(100); // 100 millisecond pulse width + + // Enable PWM output for exactly 50 pulses + pwmStartFixed(50); + + // Alternatively, enable PWM output indefinately + pwmStart(); + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "pwm.h" + +uint32_t pwmPulseWidth = CFG_PWM_DEFAULT_PULSEWIDTH; +uint32_t pwmDutyCycle = CFG_PWM_DEFAULT_DUTYCYCLE; + +// pwmMaxPulses is used by TIMER16_1_IRQHandler to turn PWM off after +// a specified number of pulses have been sent. This only relevant when +// pwmStartFixed() is used. +volatile uint32_t pwmMaxPulses = 0; + +/**************************************************************************/ +/*! + Initialises 16-bit Timer 1, and configures the MAT0 output (pin 1.9) + to send the PWM output signal. +*/ +/**************************************************************************/ +void pwmInit(void) +{ + /* Enable the clock for CT16B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1); + + /* Configure PIO1.9 as Timer1_16 MAT0 Output */ + /* Alternatively, PIO1.10 (MAT1) can also be used though + the initialisation code will need to be modified */ + IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK; + IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0; + + /* Set default pulse width (MR3)*/ + TMR_TMR16B1MR3 = pwmPulseWidth; + + /* Set default duty cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + /* Configure match control register to reset on MR3 */ + TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR3_RESET_ENABLED); + + /* External Match Register Settings for PWM */ + TMR_TMR16B1EMR = TMR_TMR16B1EMR_EMC0_TOGGLE | TMR_TMR16B1EMR_EM0; + + /* Disable Timer1 by default (enabled by pwmStart of pwmStartFixed) */ + TMR_TMR16B1TCR &= ~TMR_TMR16B1TCR_COUNTERENABLE_MASK; + + /* Enable PWM0 and PWM3 */ + TMR_TMR16B1PWMC = TMR_TMR16B1PWMC_PWM0_ENABLED | TMR_TMR16B1PWMC_PWM3_ENABLED; + + /* Make sure that the timer interrupt is enabled */ + NVIC_EnableIRQ(TIMER_16_1_IRQn); +} + +/**************************************************************************/ +/*! + Starts the PWM output +*/ +/**************************************************************************/ +void pwmStart(void) +{ + /* Disable interrupt on MR3 in case it was enabled by pwmStartFixed() */ + TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK); + + /* Enable Timer1 */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; +} + +/**************************************************************************/ +/*! + Stops the PWM output +*/ +/**************************************************************************/ +void pwmStop(void) +{ + /* Disable Timer1 */ + TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK); +} + +/**************************************************************************/ +/*! + Starts the PWM output, and stops after the specified number of + pulses. + + @param[in] pulses + The number of pulses to generate before disabling the + PWM output. The output is actually disabled in the + timer ISR. + + @warning The PWM output is actually stopped inside the 16-bit + timer ISR in "core/timer16/timer16.h". +*/ +/**************************************************************************/ +void pwmStartFixed(uint32_t pulses) +{ + pwmMaxPulses = pulses; + + /* Configure match control register to also raise an interrupt on MR3 */ + TMR_TMR16B1MCR |= (TMR_TMR16B1MCR_MR3_INT_ENABLED); + + /* Enable Timer1 (it will eventually be disabled in the ISR) */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; +} + +/**************************************************************************/ +/*! + Sets the signal's duty cycle in percent (1-100). + + @param[in] percentage + The duty-cycle in percentage (the amount of time that + the signal is 'high' relative to the time its 'low'). + + @returns -1 if an invalid percentage was supplied. Value must be + between 1 and 100. +*/ +/**************************************************************************/ +int pwmSetDutyCycle(uint32_t percentage) +{ + if ((percentage < 1) || (percentage > 100)) + { + /* Duty Cycle must be a value between 1 and 100 */ + return -1; + } + + /* Set Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - (pwmDutyCycle = percentage))) / 100; + + return 0; +} + +/**************************************************************************/ +/*! + Sets the signal's frequency/pulse-width to the specified number + of ticks. + + @param[in] ticks + The duration in clock ticks of each full pulse. + + @returns -1 if a zero-value was provided for ticks. +*/ +/**************************************************************************/ +int pwmSetFrequencyInTicks(uint16_t ticks) +{ + if (ticks < 1) + { + return -1; + } + + /* Set Pulse Width (MR3)*/ + TMR_TMR16B1MR3 = (pwmPulseWidth = ticks); + + /* Adjust Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + return 0; +} + +/**************************************************************************/ +/*! + Sets the signal's frequency/pulse-width to the specified number + of microseconds. + + @param[in] us + The duration in microseconds of each full pulse. + + @returns -1 if the supplied value exceeds the limits of the 16-bit + timer, or if a zero-value was provided. + + @Warning Because a 16-bit timer is used here by default, the + maximum frequency is quite small. Running at 36MHz, the + largest possible pulse-width/frequency is ~1,82mS or + 1820 microSeconds. At 12MHz its 5461 uS, and at 48MHz + its 1365 uS. +*/ +/**************************************************************************/ +int pwmSetFrequencyInMicroseconds(uint16_t us) +{ + if (us < 1) + { + return -1; + } + + uint32_t ticks = (((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000) * us); + if (ticks > 0xFFFF) + { + /* Delay exceeds the upper limit for the 16-bit timer */ + return -1; + } + + /* Set Pulse Width (MR3)*/ + TMR_TMR16B1MR3 = (pwmPulseWidth = ticks); + + /* Adjust Duty Cycle (MR0) */ + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; + + return 0; +} + + diff --git a/core/pwm/pwm.h b/core/pwm/pwm.h new file mode 100644 index 0000000..e03214f --- /dev/null +++ b/core/pwm/pwm.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file pwm.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PWM_H_ +#define _PWM_H_ + +#include "projectconfig.h" + +void pwmInit( void ); +void pwmStart( void ); +void pwmStop( void ); +void pwmStartFixed( uint32_t pulses ); +int pwmSetDutyCycle( uint32_t percentage ); +int pwmSetFrequencyInTicks( uint16_t ticks ); +int pwmSetFrequencyInMicroseconds(uint16_t us ); + +#endif \ No newline at end of file diff --git a/core/pwm/pwm_100us_50percent.png b/core/pwm/pwm_100us_50percent.png new file mode 100644 index 0000000..efed5f4 Binary files /dev/null and b/core/pwm/pwm_100us_50percent.png differ diff --git a/core/rom_drivers.h b/core/rom_drivers.h new file mode 100644 index 0000000..f1c4184 --- /dev/null +++ b/core/rom_drivers.h @@ -0,0 +1,58 @@ +/**************************************************************************/ +/*! + @file rom_drivers.h + @author NXP Semiconductor +*/ +/**************************************************************************/ + +#ifndef ROM_DRIVERS_H_ +#define ROM_DRIVERS_H_ + +#include "sysdefs.h" + +typedef struct _USB_DEVICE_INFO +{ + uint16_t DevType; + uint32_t DevDetailPtr; +} USB_DEV_INFO; + +typedef struct _USBD +{ + void (*init_clk_pins)(void); + void (*isr)(void); + void (*init)( USB_DEV_INFO * DevInfoPtr ); + void (*connect)(uint32_t con); +} USBD; + +typedef struct _ROM +{ + const USBD * pUSBD; +} ROM; + +typedef struct _MSC_DEVICE_INFO { + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint32_t MSCInquiryStr; + uint32_t BlockCount; + uint32_t BlockSize; + uint32_t MemorySize; + void (*MSC_Write)( uint32_t offset, uint8_t src[], uint32_t length); + void (*MSC_Read)( uint32_t offset, uint8_t dst[], uint32_t length); +} MSC_DEVICE_INFO; + +typedef struct _HID_DEVICE_INFO +{ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint32_t StrDescPtr; + uint8_t InReportCount; + uint8_t OutReportCount; + uint8_t SampleInterval; + void (*InReport)(uint8_t src[], uint32_t length); + void (*OutReport)(uint8_t dst[], uint32_t length); +} HID_DEVICE_INFO; + +#endif diff --git a/core/ssp/ssp.c b/core/ssp/ssp.c new file mode 100644 index 0000000..284945c --- /dev/null +++ b/core/ssp/ssp.c @@ -0,0 +1,299 @@ +/**************************************************************************/ +/*! + @file ssp.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for SSP/SPI communications. By default, the SSP block + is initialised in SPI master mode. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/ssp/ssp.h" + ... + cpuInit(); + sspInit(0, sspClockPolarity_High, sspClockPhase_RisingEdge); + ... + uint8_t request[SSP_FIFOSIZE]; + uint8_t response[SSP_FIFOSIZE]; + + // Send 0x9C to the slave device and wait for a response + request[0] = 0x80 | 0x1C; + // Toggle the select pin + ssp0Select(); + // Send 1 byte from the request buffer + sspSend(0, (uint8_t *)&request, 1); + // Receive 1 byte into the response buffer + sspReceive(0, (uint8_t *)&response, 1); + // Reset the select pin + ssp0Deselect(); + // Print the results + debug_printf("Ox%x ", response[0]); + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "ssp.h" +#include "core/gpio/gpio.h" + +/* Statistics for all interrupts */ +volatile uint32_t interruptRxStat = 0; +volatile uint32_t interruptOverRunStat = 0; +volatile uint32_t interruptRxTimeoutStat = 0; + +/**************************************************************************/ +/*! + @brief SSP0 interrupt handler for SPI communication + + The algorithm is, if RXFIFO is at least half full, + start receive until it's empty; if TXFIFO is at least + half empty, start transmit until it's full. + This will maximize the use of both FIFOs and performance. +*/ +/**************************************************************************/ +void SSP_IRQHandler (void) +{ + uint32_t regValue; + + regValue = SSP_SSP0MIS; + + /* Check for overrun interrupt */ + if ( regValue & SSP_SSP0MIS_RORMIS_FRMRCVD ) + { + interruptOverRunStat++; + SSP_SSP0ICR = SSP_SSP0ICR_RORIC_CLEAR; // Clear interrupt + } + + /* Check for timeout interrupt */ + if ( regValue & SSP_SSP0MIS_RTMIS_NOTEMPTY ) + { + interruptRxTimeoutStat++; + SSP_SSP0ICR = SSP_SSP0ICR_RTIC_CLEAR; // Clear interrupt + } + + /* Check if Rx buffer is at least half-full */ + if ( regValue & SSP_SSP0MIS_RXMIS_HALFFULL ) + { + // ToDo: Receive until it's empty + interruptRxStat++; + } + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the SSP0 port + + By default, SSP0 is set to SPI frame-format with 8-bit data. Pin 2.11 + is routed to serve as serial clock (SCK), and SSEL (0.2) is set to + GPIO to allow manual control of when the SPI port is enabled or + disabled. Overrun and timeout interrupts are both enabled. + + @param[in] portNum + The SPI port to use (0..1) + @param[in] polarity + Indicates whether the clock should be held high + (sspClockPolarity_High) or low (sspClockPolarity_Low) + when inactive. + @param[in] phase + Indicates whether new bits start on the leading + (sspClockPhase_RisingEdge) or falling + (sspClockPhase_FallingEdge) edge of clock transitions. + + @note sspSelect() and sspDeselect() macros have been defined in + ssp.h to control the SSEL line without having to know the + specific pin being used. +*/ +/**************************************************************************/ +void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase) +{ + gpioInit(); + + if (portNum == 0) + { + /* Reset SSP */ + SCB_PRESETCTRL &= ~SCB_PRESETCTRL_SSP0_MASK; + SCB_PRESETCTRL |= SCB_PRESETCTRL_SSP0_RESETDISABLED; + + /* Enable AHB clock to the SSP domain. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_SSP0); + + /* Divide by 1 (SSPCLKDIV also enables to SSP CLK) */ + SCB_SSP0CLKDIV = SCB_SSP0CLKDIV_DIV1; + + /* Set P0.8 to SSP MISO */ + IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK; + IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_MISO0; + + /* Set P0.9 to SSP MOSI */ + IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK; + IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_MOSI0; + + /* Set 2.11 to SSP SCK (0.6 and 0.10 can also be used) */ + #ifdef CFG_SSP0_SCKPIN_2_11 + IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO2_11; + IOCON_PIO2_11 = IOCON_PIO2_11_FUNC_SCK0; + #endif + + /* Set 0.6 to SSP SCK (2.11 and 0.10 can also be used) */ + #ifdef CFG_SSP0_SCKPIN_0_6 + IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO0_6; + IOCON_PIO0_6 = IOCON_PIO0_6_FUNC_SCK; + #endif + + /* Set P0.2/SSEL to GPIO output and high */ + IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK; + IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_GPIO; + gpioSetDir(SSP0_CSPORT, SSP0_CSPIN, 1); + gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1); + gpioSetPullup(&IOCON_PIO0_2, gpioPullupMode_Inactive); // Board has external pull-up + + /* If SSP0CLKDIV = DIV1 -- (PCLK / (CPSDVSR × [SCR+1])) = (72,000,000 / (2 x [8 + 1])) = 4.0 MHz */ + uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit + | SSP_SSP0CR0_FRF_SPI // Frame format = SPI + | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 + + // Set clock polarity + if (polarity == sspClockPolarity_High) + configReg |= SSP_SSP0CR0_CPOL_HIGH; // Clock polarity = High between frames + else + configReg &= ~SSP_SSP0CR0_CPOL_MASK; // Clock polarity = Low between frames + + // Set edge transition + if (phase == sspClockPhase_FallingEdge) + configReg |= SSP_SSP0CR0_CPHA_SECOND; // Clock out phase = Trailing edge clock transition + else + configReg &= ~SSP_SSP0CR0_CPHA_MASK; // Clock out phase = Leading edge clock transition + + // Assign config values to SSP0CR0 + SSP_SSP0CR0 = configReg; + + /* Clock prescale register must be even and at least 2 in master mode */ + SSP_SSP0CPSR = SSP_SSP0CPSR_CPSDVSR_DIV2; + + /* Clear the Rx FIFO */ + uint8_t i, Dummy=Dummy; + for ( i = 0; i < SSP_FIFOSIZE; i++ ) + { + Dummy = SSP_SSP0DR; + } + + /* Enable the SSP Interrupt */ + NVIC_EnableIRQ(SSP_IRQn); + + /* Set SSPINMS registers to enable interrupts + * enable all error related interrupts */ + SSP_SSP0IMSC = ( SSP_SSP0IMSC_RORIM_ENBL // Enable overrun interrupt + | SSP_SSP0IMSC_RTIM_ENBL); // Enable timeout interrupt + + /* Enable device and set it to master mode, no loopback */ + SSP_SSP0CR1 = SSP_SSP0CR1_SSE_ENABLED | SSP_SSP0CR1_MS_MASTER | SSP_SSP0CR1_LBM_NORMAL; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Sends a block of data to the SSP0 port + + @param[in] portNum + The SPI port to use (0..1) + @param[in] buf + Pointer to the data buffer + @param[in] length + Block length of the data buffer +*/ +/**************************************************************************/ +void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length) +{ + uint32_t i; + uint8_t Dummy = Dummy; + + if (portNum == 0) + { + for (i = 0; i < length; i++) + { + /* Move on only if NOT busy and TX FIFO not full. */ + while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL); + SSP_SSP0DR = *buf; + buf++; + + while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY ); + /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO + on MISO. Otherwise, when SSP0Receive() is called, previous data byte + is left in the FIFO. */ + Dummy = SSP_SSP0DR; + } + } + + return; +} + +/**************************************************************************/ +/*! + @brief Receives a block of data from the SSP0 port + + @param[in] portNum + The SPI port to use (0..1) + @param[in] buf + Pointer to the data buffer + @param[in] length + Block length of the data buffer +*/ +/**************************************************************************/ +void sspReceive(uint8_t portNum, uint8_t *buf, uint32_t length) +{ + uint32_t i; + + if (portNum == 0) + { + for ( i = 0; i < length; i++ ) + { + /* As long as the receive FIFO is not empty, data can be received. */ + SSP_SSP0DR = 0xFF; + + /* Wait until the Busy bit is cleared */ + while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY ); + + *buf = SSP_SSP0DR; + buf++; + } + } + + return; +} + diff --git a/core/ssp/ssp.h b/core/ssp/ssp.h new file mode 100644 index 0000000..3deab4e --- /dev/null +++ b/core/ssp/ssp.h @@ -0,0 +1,85 @@ +/**************************************************************************/ +/*! + @file ssp.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SSP_H_ +#define _SSP_H_ + +#include "projectconfig.h" +#include "core/gpio/gpio.h" + +#define SSP_FIFOSIZE 8 /* SPI read and write buffer size */ +#define SSP_MAX_TIMEOUT 0xFF + +#define SSP0_CSPORT 0 +#define SSP0_CSPIN 2 + +/* Macro definitions to enable and disable SPI */ +#define ssp0Select() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 0);} while (0) +#define ssp0Deselect() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1);} while (0) + +/**************************************************************************/ +/*! + Indicates whether the clock should be high or low between frames. +*/ +/**************************************************************************/ +typedef enum sspClockPolarity_e +{ + sspClockPolarity_Low = 0, + sspClockPolarity_High +} +sspClockPolarity_t; + +/**************************************************************************/ +/*! + Indicates whether the bits start at the rising or falling edge of + the clock transition. +*/ +/**************************************************************************/ +typedef enum sspClockPhase_e +{ + sspClockPhase_RisingEdge = 0, + sspClockPhase_FallingEdge +} +sspClockPhase_t; + +extern void SSP_IRQHandler (void); +void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase); +void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length); +void sspReceive (uint8_t portNum, uint8_t *buf, uint32_t length); + +#endif diff --git a/core/systick/systick.c b/core/systick/systick.c new file mode 100644 index 0000000..ebf50b8 --- /dev/null +++ b/core/systick/systick.c @@ -0,0 +1,229 @@ +/**************************************************************************/ +/*! + @file systick.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Controls the 24-bit 'system tick' clock, which can be used as a + generic timer or to control time sharing with an embedded real-time + operating system (such as FreeRTOS). + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "core/systick/systick.h" + + void main (void) + { + cpuInit(); + + // Start systick timer with one tick every 10ms + systickInit(10); + + while(1) + { + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "systick.h" + +#ifdef CFG_SDCARD +#include "drivers/fatfs/diskio.h" +volatile uint32_t fatTicks = 0; +#endif + +volatile uint32_t systickTicks = 0; // 1ms tick counter +volatile uint32_t systickRollovers = 0; + +/**************************************************************************/ +/*! + @brief Systick interrupt handler +*/ +/**************************************************************************/ +void SysTick_Handler (void) +{ + systickTicks++; + + // Increment rollover counter + if (systickTicks == 0xFFFFFFFF) systickRollovers++; + + #ifdef CFG_SDCARD + fatTicks++; + if (fatTicks == 10) + { + fatTicks = 0; + disk_timerproc(); + } + #endif +} + +/**************************************************************************/ +/*! + @brief Configures the systick timer + + @param[in] ticks + The number of clock cycles between each tick of the + systick timer. for example, 'CFG_CPU_CCLK / 1000' = + 1 millisecond. This value must not exceed 0x00FFFFFF. +*/ +/**************************************************************************/ +static uint32_t systickConfig(uint32_t ticks) +{ + // Check if 'ticks' is greater than maximum value + if (ticks > SYSTICK_STRELOAD_MASK) + { + return (1); + } + + // Reset counter + systickTicks = 0; + + // Set reload register + SYSTICK_STRELOAD = (ticks & SYSTICK_STRELOAD_MASK) - 1; + + // Load the systick counter value + SYSTICK_STCURR = 0; + + // Enable systick IRQ and timer + SYSTICK_STCTRL = SYSTICK_STCTRL_CLKSOURCE | + SYSTICK_STCTRL_TICKINT | + SYSTICK_STCTRL_ENABLE; + + return (0); +} + +/**************************************************************************/ +/*! + @brief Initialises the systick timer + + @param[in] delayMs + The number of milliseconds between each tick of the systick + timer. + + @note The shortest possible delay is 1 millisecond, which will + allow fine grained delays, but will cause more load on the + system than a 10mS delay. The resolution of the systick + timer needs to be balanced with the amount of processing + time you can spare. The delay should really only be set + to 1 mS if you genuinely have a need for 1mS delays, + otherwise a higher value like 5 or 10 mS is probably + more appropriate. +*/ +/**************************************************************************/ +void systickInit (uint32_t delayMs) +{ + systickConfig ((CFG_CPU_CCLK / 1000) * delayMs); +} + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for 'delayTicks' ticks on the + systick timer. For example: systickDelay(100) would cause + a blocking delay for 100 ticks of the systick timer. + + @param[in] delayTicks + The number of systick ticks to cause a blocking delay for + + @Note This function takes into account the fact that the tick + counter may eventually roll over to 0 once it reaches + 0xFFFFFFFF. +*/ +/**************************************************************************/ +void systickDelay (uint32_t delayTicks) +{ + uint32_t curTicks; + curTicks = systickTicks; + + // Make sure delay is at least 1 tick in case of division, etc. + if (delayTicks == 0) delayTicks = 1; + + if (curTicks > 0xFFFFFFFF - delayTicks) + { + // Rollover will occur during delay + while (systickTicks >= curTicks) + { + while (systickTicks < (delayTicks - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((systickTicks - curTicks) < delayTicks); + } +} + +/**************************************************************************/ +/*! + @brief Returns the current value of the systick timer counter. + This value is incremented by one every time an interrupt + fires for the systick timer. +*/ +/**************************************************************************/ +uint32_t systickGetTicks(void) +{ + return systickTicks; +} + +/**************************************************************************/ +/*! + @brief Returns the current value of the systick timer rollover + counter. This value is incremented by one every time the + tick counter rolls over from 0xFFFFFFFF to 0. +*/ +/**************************************************************************/ +uint32_t systickGetRollovers(void) +{ + return systickRollovers; +} + +/**************************************************************************/ +/*! + @brief Returns the approximate number of seconds that the + systick timer has been running. +*/ +/**************************************************************************/ +uint32_t systickGetSecondsActive(void) +{ + uint32_t currentTick = systickTicks; + uint32_t rollovers = systickRollovers; + uint32_t secsActive = currentTick / (1000 / CFG_SYSTICK_DELAY_IN_MS); + secsActive += rollovers * (0xFFFFFFFF / (1000 / CFG_SYSTICK_DELAY_IN_MS)); + + return secsActive; +} + diff --git a/core/systick/systick.h b/core/systick/systick.h new file mode 100644 index 0000000..a184a3d --- /dev/null +++ b/core/systick/systick.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file systick.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SYSTICK_H_ +#define _SYSTICK_H_ + +#include "projectconfig.h" + +void systickInit (uint32_t delayMs); +void systickDelay (uint32_t delayTicks); +uint32_t systickGetTicks(void); +uint32_t systickGetRollovers(void); +uint32_t systickGetSecondsActive(void); + +#endif \ No newline at end of file diff --git a/core/timer16/timer16.c b/core/timer16/timer16.c new file mode 100644 index 0000000..38fca82 --- /dev/null +++ b/core/timer16/timer16.c @@ -0,0 +1,505 @@ +/**************************************************************************/ +/*! + @file timer16.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Generic code for both 16-bit timers. + + @warning 16-bit timers are limited to roughly ~0.91ms (or 910uS) on + a system running at 72MHz since: + @code + 1 mS = CFG_CPU_CCLK / 1000 + = 72000000 / 1000 + = 72000 'ticks' + @endcode + Meaning that 0xFFFF (65535) 'ticks' = 0.910208 milliseconds + or 910 microseconds. + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + // Instantiated in timer16.h + extern volatile uint32_t timer16_0_counter; + ... + cpuInit(); + + // Initialise timer0 with a delay of 0xFFFF, which will cause the + // timer interrupt to fire every 65535 ticks and increment + // timer16_0_counter by 1 + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + // At this point timer16_0_counter should start incrementing by 1 + // every 65535 ticks + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "timer16.h" + +volatile uint32_t timer16_0_counter = 0; +volatile uint32_t timer16_1_counter = 0; + +#ifdef CFG_PWM + volatile uint32_t pwmCounter = 0; + extern volatile uint32_t pwmMaxPulses; // See drivers/pwm/pwm.c +#endif + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + clock ticks. + + @note The exact duration of this delay depends on the speed of the + system clock, but it will invariably be short because of the + 16-bit limitation. For example, on a system with a 72MHz + clock, a 1mS delay would be equal to 72,000 ticks, which is + already above the maximum 16-bit value of 65,535. Thus, the + maximum delay measured in mS with a 72MHz clock is ~0.91mS. + + @param[in] timerNum + The 16-bit timer to user (0..1) + @param[in] delayInTicks + The number of clock ticks to delay (0..65534) + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + int main(void) + { + cpuInit(); + + // Initialise timer 0 ... delay is provided but not used here + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + while(1) + { + // Cause blocking delay for 36000 ticks (0.5mS @ 72MHz) + // Note: The delay must be 65534 or less (16-bit value) + timer16DelayTicks(0, 36000); + } + } + @endcode +*/ +/**************************************************************************/ +void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks) +{ + // ToDo: Verify incoming value + + if (timerNum == 0) + { + /* Reset the timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B0PR = 0x00; + + TMR_TMR16B0MR0 = delayInTicks; + + /* Reset all interrupts */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED); + } + + else if (timerNum == 1) + { + /* Reset the timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B1PR = 0x00; + + TMR_TMR16B1MR0 = delayInTicks; + + /* Reset all interrupts */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED); + } + + return; +} + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + microseconds + + @warning The maximum delay in uS will depend on the clock speed, + but running at 72MHz the maximum delay (MR = 0xFFFF) + would be 910uS (0xFFFF / 72 = 910), or 0.91 milliseconds. + + @param[in] timerNum + The 16-bit timer to user (0..1) + @param[in] delayInUs + The number of microseconds to wait + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer16/timer16.h" + + int main(void) + { + cpuInit(); + + // Initialise timer 0 ... delay is provided but not used here + timer16Init(0, 0xFFFF); + + // Enable the timer + timer16Enable(0); + + while(1) + { + // Cause blocking delay for 500 microseconds (0.5mS) + timer16DelayUS(0, 500); + } + } + @endcode +*/ +/**************************************************************************/ +void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS) +{ + // ToDo: Check if the appropriate timer is enabled first? + + if (timerNum == 0) + { + /* Reset the timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B0PR = 0x00; + + TMR_TMR16B0MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000); + + /* Reset all interrupts */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED); + } + + else if (timerNum == 1) + { + /* Reset the timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + + /* Set the prescaler to zero */ + TMR_TMR16B1PR = 0x00; + + TMR_TMR16B1MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000); + + /* Reset all interrupts */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL; + + /* Stop timer on match (MR0) */ + TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED; + + /* Start timer */ + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + + /* Wait until the delay time has elapsed */ + while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED); + } + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 16-bit timer 0 +*/ +/**************************************************************************/ +void TIMER16_0_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR16B0IR = TMR_TMR16B0IR_MR0; + + /* Increment timer counter by 1 (it will automatically roll back to 0) */ + timer16_0_counter++; + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 16-bit timer 1 +*/ +/**************************************************************************/ +void TIMER16_1_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MR0; + + /* Increment timer counter by 1 (it will automatically roll back to 0) */ + timer16_1_counter++; + + #ifdef CFG_PWM + /* Check if the PWM output should be disabled after pwmMaxPulses pulses */ + /* See "drivers/pwm/pwm.c" */ + if (TMR_TMR16B1IR & TMR_TMR16B1IR_MR3) + { + /* Clear the interrupt flag */ + TMR_TMR16B1IR = TMR_TMR16B1IR_MR3; + + if (pwmMaxPulses > 0) + { + pwmCounter++; + if (pwmCounter == pwmMaxPulses) + { + /* Disable interrupt on MR3 */ + TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK); + /* Disable Timer */ + TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK); + /* Reset the counter variables */ + pwmCounter = 0; + pwmMaxPulses = 0; + } + } + } + #endif + + return; +} + +/**************************************************************************/ +/*! + @brief Enables the specified timer + + @param[in] timerNum + The 16-bit timer to enable (0..1) +*/ +/**************************************************************************/ +void timer16Enable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED; + } + + else if (timerNum == 1) + { + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Disables the specified timer + + @param[in] timerNum + The 16-bit timer to disable (0..1) +*/ +/**************************************************************************/ +void timer16Disable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_DISABLED; + } + + else if (timerNum == 1) + { + TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_DISABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Resets the specified timer + + @param[in] timerNum + The 16-bit timer to reset (0..1) +*/ +/**************************************************************************/ +void timer16Reset(uint8_t timerNum) +{ + uint32_t regVal; + + if ( timerNum == 0 ) + { + regVal = TMR_TMR16B0TCR; + regVal |= TMR_TMR16B0TCR_COUNTERRESET_ENABLED; + TMR_TMR16B0TCR = regVal; + } + + else if (timerNum == 1) + { + regVal = TMR_TMR16B1TCR; + regVal |= TMR_TMR16B1TCR_COUNTERRESET_ENABLED; + TMR_TMR16B1TCR = regVal; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the specified 16-bit timer, sets the timer + interval, resets the timer, and configures the interrupt + handler. + + Initialises a 16-bit timer with the supplied timer interval (the + amount of time that passes between each timer 'tick'). Every time that + this interval elapses, the timer's interrupt will be fired and the + appropriate counter variable will be incremented by one (For example, + with CT16B0, 'timer16_0_counter' would be incremented). + + @param[in] timerNum + The 16-bit timer to initiliase (0..1) + @param[in] timerInterval + The number of clock 'ticks' between resets (0..65534) + + @warning Care needs to be taken when configuring the timers since + the pins are all multiplexed with other peripherals. This + code is provided as a starting point, but it will need to + be adjusted according to your own situation and + pin/peripheral requirements +*/ +/**************************************************************************/ +void timer16Init(uint8_t timerNum, uint16_t timerInterval) +{ + // If timerInterval is invalid, use the default value + if (timerInterval < 1) + { + timerInterval = TIMER16_DEFAULTINTERVAL; + } + + if ( timerNum == 0 ) + { + /* Enable the clock for CT16B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B0); + + /* The physical pins associated with CT16B0 are not enabled by + default in order to avoid conflicts with other peripherals. + Pin 0.10 (CT16B0_MAT2), for example, can not be used while + debugging with a hardware debugger. If you require one or + more of these pins, simply uncomment the code below */ + + /* Configure PIO0.2 as Timer0_16 CAP0 */ + // IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK; + // IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_CT16B0_CAP0; + + /* Configure PIO0.8 as Timer0_16 MAT0 */ + // IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK; + // IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_CT16B0_MAT0; + + /* Configure PIO0.9 as Timer0_16 MAT1 */ + // IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK; + // IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_CT16B0_MAT1; + + /* Configure PIO0.10 as Timer0_16 MAT3 */ + // IOCON_JTAG_TCK_PIO0_10 &= ~IOCON_JTAG_TCK_PIO0_10_FUNC_MASK; + // IOCON_JTAG_TCK_PIO0_10 |= IOCON_JTAG_TCK_PIO0_10_FUNC_CT16B0_MAT2; + + timer16_0_counter = 0; + TMR_TMR16B0MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR16B0MCR = (TMR_TMR16B0MCR_MR0_INT_ENABLED | TMR_TMR16B0MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER0 interrupt */ + NVIC_EnableIRQ(TIMER_16_0_IRQn); + } + + else if ( timerNum == 1 ) + { + /* Enable the clock for CT16B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1); + + /* The physical pins associated with CT16B0 are not enabled by + default in order to avoid conflicts with other peripherals. + Pin 0.10 (CT16B0_MAT2), for example, can not be used while + debugging with a hardware debugger. If you require one or + more of these pins, simply uncomment the code below */ + + /* Configure PIO1.8 as Timer1_16 CAP0 */ + // IOCON_PIO1_8 &= ~IOCON_PIO1_8_FUNC_MASK; + // IOCON_PIO1_8 |= IOCON_PIO1_8_FUNC_CT16B1_CAP0; + + /* Configure PIO1.9 as Timer1_16 MAT0 */ + // IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK; + // IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0; + + /* Configure PIO1.10 as Timer1_16 MAT1 */ + // IOCON_PIO1_10 &= ~IOCON_PIO1_10_FUNC_MASK; + // IOCON_PIO1_10 |= IOCON_PIO1_10_FUNC_CT16B1_MAT1; + + timer16_1_counter = 0; + TMR_TMR16B1MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR0_INT_ENABLED | TMR_TMR16B1MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER1 Interrupt */ + NVIC_EnableIRQ(TIMER_16_1_IRQn); + } + return; +} diff --git a/core/timer16/timer16.h b/core/timer16/timer16.h new file mode 100644 index 0000000..2130b69 --- /dev/null +++ b/core/timer16/timer16.h @@ -0,0 +1,59 @@ +/**************************************************************************/ +/*! + @file timer16.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __TIMER16_H__ +#define __TIMER16_H__ + +#include "projectconfig.h" + +#define TIMER16_DEFAULTINTERVAL (0xFFFF) // ~0.91mS @ 72MHz, ~1.37mS @ 48MHz + +#define TIMER16_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000) +#define TIMER16_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000) + +void TIMER16_0_IRQHandler(void); +void TIMER16_1_IRQHandler(void); + +void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks); +void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS); +void timer16Enable(uint8_t timerNum); +void timer16Disable(uint8_t timerNum); +void timer16Reset(uint8_t timerNum); +void timer16Init(uint8_t timerNum, uint16_t timerInterval); + +#endif diff --git a/core/timer32/timer32.c b/core/timer32/timer32.c new file mode 100644 index 0000000..b768905 --- /dev/null +++ b/core/timer32/timer32.c @@ -0,0 +1,344 @@ +/**************************************************************************/ +/*! + @file timer32.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for 32-bit timers. By default, the timers are configured + to generate an interrupt once every 100 microseconds, incrementing a + global variable once per tick. + + @warning Please note that the ROM-based USB drivers on the LPC1343 + require the use of 32-bit Timer 1. If you plan on using the + ROM-based USB functionality, you should restrict your timer + usage to 32-bit timer 0. + + @section Example + + @code + #include "/core/cpu/cpu.h" + #include "/core/timer32/timer32.h" + ... + cpuInit(); + + // Initialise 32-bit timer 0 with 100uS ticks + timer32Init(0, TIMER32_DEFAULTINTERVAL); + + // Enable timer 0 + timer32Enable(0); + + // Cause a blocking delay for 1 second (1000mS) + timer32Delay(0, TIMER32_DELAY_1MS * 1000); + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "timer32.h" + +volatile uint32_t timer32_0_counter = 0; +volatile uint32_t timer32_1_counter = 0; + +/**************************************************************************/ +/*! + @brief Causes a blocking delay for the specified number of + timer ticks. The duration of each 'tick' is determined by + the 'timerInterval' property supplied to timer32Init. + + @param[in] timerNum + The 32-bit timer to user (0..1) + @param[in] delay + The number of counter increments to wait +*/ +/**************************************************************************/ +void timer32Delay(uint8_t timerNum, uint32_t delay) +{ + uint32_t curTicks; + + if (timerNum == 0) + { + curTicks = timer32_0_counter; + if (curTicks > 0xFFFFFFFF - delay) + { + // Rollover will occur during delay + while (timer32_0_counter >= curTicks) + { + while (timer32_0_counter < (delay - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((timer32_0_counter - curTicks) < delay); + } + } + + else if (timerNum == 1) + { + curTicks = timer32_1_counter; + if (curTicks > 0xFFFFFFFF - delay) + { + // Rollover will occur during delay + while (timer32_1_counter >= curTicks) + { + while (timer32_1_counter < (delay - (0xFFFFFFFF - curTicks))); + } + } + else + { + while ((timer32_1_counter - curTicks) < delay); + } + } + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 32-bit timer 0 +*/ +/**************************************************************************/ +void TIMER32_0_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR32B0IR = TMR_TMR32B0IR_MR0; + + /* If you wish to perform some action after each timer 'tick' (such as + incrementing a counter variable) you can do so here */ + timer32_0_counter++; + + return; +} + +/**************************************************************************/ +/*! + @brief Interrupt handler for 32-bit timer 1 +*/ +/**************************************************************************/ +void TIMER32_1_IRQHandler(void) +{ + /* Clear the interrupt flag */ + TMR_TMR32B1IR = TMR_TMR32B1IR_MR0; + + /* If you wish to perform some action after each timer 'tick' (such as + incrementing a counter variable) you can do so here */ + timer32_1_counter++; + + return; +} + +/**************************************************************************/ +/*! + @brief Enables the specified timer + + @param[in] timerNum + The 32-bit timer to enable (0..1) +*/ +/**************************************************************************/ +void timer32Enable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED; + } + + else if (timerNum == 1) + { + TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_ENABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Disables the specified timer + + @param[in] timerNum + The 32-bit timer to disable (0..1) +*/ +/**************************************************************************/ +void timer32Disable(uint8_t timerNum) +{ + if ( timerNum == 0 ) + { + TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED; + } + + else if (timerNum == 1) + { + TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_DISABLED; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Resets the specified timer + + @param[in] timerNum + The 32-bit timer to reset (0..1) +*/ +/**************************************************************************/ +void timer32Reset(uint8_t timerNum) +{ + uint32_t regVal; + + if ( timerNum == 0 ) + { + regVal = TMR_TMR32B0TCR; + regVal |= TMR_TMR32B0TCR_COUNTERRESET_ENABLED; + TMR_TMR32B0TCR = regVal; + } + + else if (timerNum == 1) + { + regVal = TMR_TMR32B1TCR; + regVal |= TMR_TMR32B1TCR_COUNTERRESET_ENABLED; + TMR_TMR32B1TCR = regVal; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Initialises the specified 32-bit timer, and configures the + timer to raise an interrupt and reset on match on MR0. + + @param[in] timerNum + The 32-bit timer to initiliase (0..1) + @param[in] timerInterval + The number of clock 'ticks' between resets (0..0xFFFFFFFF) + + @note Care needs to be taken when configuring the timers since the + pins are all multiplexed with other peripherals. This code is + provided as a starting point, but it will need to be adjusted + according to your own situation and pin/peripheral requirements +*/ +/**************************************************************************/ +void timer32Init(uint8_t timerNum, uint32_t timerInterval) +{ + // If timerInterval is invalid, use the default value + if (timerInterval < 1) + { + timerInterval = TIMER32_DEFAULTINTERVAL; + } + + if ( timerNum == 0 ) + { + /* Enable the clock for CT32B0 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); + + /* The physical pins associated with CT32B0 are not enabled by + default in order to avoid conflicts with other peripherals. If + you wish to use any of the pin-dependant functionality, simply + uncomment the appropriate lines below. */ + + /* Configure PIO1.5 as Timer0_32 CAP0 */ + // IOCON_PIO1_5 &= ~IOCON_PIO1_5_FUNC_MASK; + // IOCON_PIO1_5 |= IOCON_PIO1_5_FUNC_CT32B0_CAP0; + + /* Configure PIO1.6 as Timer0_32 MAT0 */ + // IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK; + // IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_CT32B0_MAT0; + + /* Configure PIO1.7 as Timer0_32 MAT1 */ + // IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK; + // IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_CT32B0_MAT1; + + /* Configure PIO0.1 as Timer0_32 MAT2 */ + // IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + // IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2; + + /* Configure PIO0.11 as Timer0_32 MAT3 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TDI_PIO0_11 &= ~IOCON_JTAG_TDI_PIO0_11_FUNC_MASK; + // IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_CT32B0_MAT3; + + timer32_0_counter = 0; + TMR_TMR32B0MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B0MCR = (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER0 interrupt */ + NVIC_EnableIRQ(TIMER_32_0_IRQn); + } + + else if ( timerNum == 1 ) + { + /* Enable the clock for CT32B1 */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1); + + /* The physical pins associated with CT32B0 are not enabled by + default in order to avoid conflicts with other peripherals. */ + + /* Configure PIO1.0 as Timer1_32 CAP0 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TMS_PIO1_0 &= ~IOCON_JTAG_TMS_PIO1_0_FUNC_MASK; + // IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_CT32B1_CAP0; + + /* Configure PIO1.1 as Timer1_32 MAT0 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_TDO_PIO1_1 &= ~IOCON_JTAG_TDO_PIO1_1_FUNC_MASK; + // IOCON_JTAG_TDO_PIO1_1 |= IOCON_JTAG_TDO_PIO1_1_FUNC_CT32B1_MAT0; + + /* Configure PIO1.2 as Timer1_32 MAT1 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_JTAG_nTRST_PIO1_2 &= ~IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK; + // IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_CT32B1_MAT1; + + /* Configure PIO1.3 as Timer1_32 MAT2 */ + /* Note: This pint can not be used with JTAG/SWD */ + // IOCON_SWDIO_PIO1_3 &= ~IOCON_SWDIO_PIO1_3_FUNC_MASK; + // IOCON_SWDIO_PIO1_3 |= IOCON_SWDIO_PIO1_3_FUNC_CT32B1_MAT2; + + /* Configure PIO1.4 as Timer1_32 MAT3 */ + // IOCON_PIO1_4 &= ~IOCON_PIO1_4_FUNC_MASK; + // IOCON_PIO1_4 |= IOCON_PIO1_4_FUNC_CT32B1_MAT3; + + timer32_1_counter = 0; + TMR_TMR32B1MR0 = timerInterval; + + /* Configure match control register to raise an interrupt and reset on MR0 */ + TMR_TMR32B1MCR = (TMR_TMR32B1MCR_MR0_INT_ENABLED | TMR_TMR32B1MCR_MR0_RESET_ENABLED); + + /* Enable the TIMER1 Interrupt */ + NVIC_EnableIRQ(TIMER_32_1_IRQn); + } + return; +} + + diff --git a/core/timer32/timer32.h b/core/timer32/timer32.h new file mode 100644 index 0000000..b7135a8 --- /dev/null +++ b/core/timer32/timer32.h @@ -0,0 +1,66 @@ +/**************************************************************************/ +/*! + @file timer32.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __TIMER32_H__ +#define __TIMER32_H__ + +#include "projectconfig.h" + +#define TIMER32_CCLK_1US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000) +#define TIMER32_CCLK_10US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100000) +#define TIMER32_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000) +#define TIMER32_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000) +#define TIMER32_CCLK_10MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100) +#define TIMER32_CCLK_100MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10) +#define TIMER32_CCLK_1S (CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) +#define TIMER32_DEFAULTINTERVAL (TIMER32_CCLK_100US) + +#define TIMER32_DELAY_100US (1) // 100uS delay = 1 tick +#define TIMER32_DELAY_1MS (10) // 1mS delay = 10 ticks +#define TIMER32_DELAY_1S (10000) // 1S delay = 10000 ticks + +void TIMER32_0_IRQHandler(void); +void TIMER32_1_IRQHandler(void); + +void timer32Delay(uint8_t timerNum, uint32_t delay); +void timer32Enable(uint8_t timerNum); +void timer32Disable(uint8_t timerNum); +void timer32Reset(uint8_t timerNum); +void timer32Init(uint8_t timerNum, uint32_t timerInterval); + +#endif diff --git a/core/uart/uart.c b/core/uart/uart.c new file mode 100644 index 0000000..57589ff --- /dev/null +++ b/core/uart/uart.c @@ -0,0 +1,347 @@ +/**************************************************************************/ +/*! + @file uart.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Generic code for UART-based communication. Incoming text is stored + in a FIFO Queue for safer processing. + + @section Example: Sending text via UART + + @code + #include "core/cpu/cpu.h" + #include "core/uart/uart.h" + ... + #define UARTBUFFERSIZE 5 + ... + cpuInit(); + uartInit(57600); + ... + uint8_t uartBuffer[UARTBUFFERSIZE] = { 'T', 'e', 's', 't', '\n' }; + + // Send contents of uartBuffer + uartSend((uint8_t *)uartBuffer, UARTBUFFERSIZE); + @endcode + + @section Example: Reading from UART + + @code + + #include "core/cpu/cpu.h" + #include "core/uart/uart.h" + + cpuInit(); + uartInit(57600); + + // Get a reference to the UART control block + uart_pcb_t *pcb = uartGetPCB(); + + // Read any text available in the queue + while (uartRxBufferDataPending()) + { + // Read the first available character + uint8_t c = uartRxBufferRead(); + + // read out the data in the buffer and echo it back to the host. + switch (c) + { + case '\r': + printf("\n\r"); + break; + default: + printf("%c", c); + break; + } + } + + #endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include + +#include "uart.h" + +#ifdef CFG_INTERFACE_UART + #include "core/cmd/cmd.h" +#endif + +/**************************************************************************/ +/*! + UART protocol control block, which is used to safely access the + RX FIFO buffer from elsewhere in the code. This should be accessed + through 'uartGetPCB()'. +*/ +/**************************************************************************/ +static uart_pcb_t pcb; + +/**************************************************************************/ +/*! + IRQ to handle incoming data, etc. +*/ +/**************************************************************************/ +void UART_IRQHandler(void) +{ + uint8_t IIRValue, LSRValue; + uint8_t Dummy = Dummy; + + IIRValue = UART_U0IIR; + IIRValue &= ~(UART_U0IIR_IntStatus_MASK); /* skip pending bit in IIR */ + IIRValue &= UART_U0IIR_IntId_MASK; /* check bit 1~3, interrupt identification */ + + // 1.) Check receiver line status + if (IIRValue == UART_U0IIR_IntId_RLS) + { + LSRValue = UART_U0LSR; + // Check for errors + if (LSRValue & (UART_U0LSR_OE | UART_U0LSR_PE | UART_U0LSR_FE | UART_U0LSR_RXFE | UART_U0LSR_BI)) + { + /* There are errors or break interrupt */ + /* Read LSR will clear the interrupt */ + pcb.status = LSRValue; + Dummy = UART_U0RBR; /* Dummy read on RX to clear interrupt, then bail out */ + return; + } + // No error and receive data is ready + if (LSRValue & UART_U0LSR_RDR_DATA) + { + /* If no error on RLS, normal ready, save into the data buffer. */ + /* Note: read RBR will clear the interrupt */ + uartRxBufferWrite(UART_U0RBR); + } + } + + // 2.) Check receive data available + else if (IIRValue == UART_U0IIR_IntId_RDA) + { + // Add incoming text to UART buffer + uartRxBufferWrite(UART_U0RBR); + } + + // 3.) Check character timeout indicator + else if (IIRValue == UART_U0IIR_IntId_CTI) + { + /* Bit 9 as the CTI error */ + pcb.status |= 0x100; + } + + // 4.) Check THRE (transmit holding register empty) + else if (IIRValue == UART_U0IIR_IntId_THRE) + { + /* Check status in the LSR to see if valid data in U0THR or not */ + LSRValue = UART_U0LSR; + if (LSRValue & UART_U0LSR_THRE) + { + pcb.pending_tx_data = 0; + } + else + { + pcb.pending_tx_data= 1; + } + } + return; +} + +/**************************************************************************/ +/*! + @brief Get a pointer to the UART's protocol control block, which can + be used to control the RX FIFO buffer and check whether UART + has already been initialised or not. + + @section Example + + @code + // Make sure that UART is initialised + uart_pcb_t *pcb = uartGetPCB(); + if (!pcb->initialised) + { + uartInit(CFG_UART_BAUDRATE); + } + @endcode + +*/ +/**************************************************************************/ +uart_pcb_t *uartGetPCB() +{ + return &pcb; +} + +/**************************************************************************/ +/*! + @brief Initialises UART at the specified baud rate. + + @param[in] baudRate + The baud rate to use when configuring the UART. +*/ +/**************************************************************************/ +void uartInit(uint32_t baudrate) +{ + uint32_t fDiv; + uint32_t regVal; + + NVIC_DisableIRQ(UART_IRQn); + + // Clear protocol control blocks + memset(&pcb, 0, sizeof(uart_pcb_t)); + pcb.pending_tx_data = 0; + uartRxBufferInit(); + + /* Set 1.6 UART RXD */ + IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK; + IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_UART_RXD; + + /* Set 1.7 UART TXD */ + IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK; + IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_UART_TXD; + + /* Enable UART clock */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_UART); + SCB_UARTCLKDIV = SCB_UARTCLKDIV_DIV1; /* divided by 1 */ + + /* 8 bits, no Parity, 1 Stop bit */ + UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars | + UART_U0LCR_Stop_Bit_Select_1Bits | + UART_U0LCR_Parity_Disabled | + UART_U0LCR_Parity_Select_OddParity | + UART_U0LCR_Break_Control_Disabled | + UART_U0LCR_Divisor_Latch_Access_Enabled); + + /* Baud rate */ + regVal = SCB_UARTCLKDIV; + fDiv = (((CFG_CPU_CCLK * SCB_SYSAHBCLKDIV)/regVal)/16)/baudrate; + + UART_U0DLM = fDiv / 256; + UART_U0DLL = fDiv % 256; + + /* Set DLAB back to 0 */ + UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars | + UART_U0LCR_Stop_Bit_Select_1Bits | + UART_U0LCR_Parity_Disabled | + UART_U0LCR_Parity_Select_OddParity | + UART_U0LCR_Break_Control_Disabled | + UART_U0LCR_Divisor_Latch_Access_Disabled); + + /* Enable and reset TX and RX FIFO. */ + UART_U0FCR = (UART_U0FCR_FIFO_Enabled | + UART_U0FCR_Rx_FIFO_Reset | + UART_U0FCR_Tx_FIFO_Reset); + + /* Read to clear the line status. */ + regVal = UART_U0LSR; + + /* Ensure a clean start, no data in either TX or RX FIFO. */ + while (( UART_U0LSR & (UART_U0LSR_THRE|UART_U0LSR_TEMT)) != (UART_U0LSR_THRE|UART_U0LSR_TEMT) ); + while ( UART_U0LSR & UART_U0LSR_RDR_DATA ) + { + /* Dump data from RX FIFO */ + regVal = UART_U0RBR; + } + + /* Set the initialised flag in the protocol control block */ + pcb.initialised = 1; + pcb.baudrate = baudrate; + + /* Enable the UART Interrupt */ + NVIC_EnableIRQ(UART_IRQn); + UART_U0IER = UART_U0IER_RBR_Interrupt_Enabled | UART_U0IER_RLS_Interrupt_Enabled; + + return; +} + +/**************************************************************************/ +/*! + @brief Sends the contents of supplied text buffer over UART. + + @param[in] bufferPtr + Pointer to the text buffer + @param[in] bufferPtr + The size of the text buffer + + @section Example + + @code + // Set 5-character text buffer + uint8_t uartBuffer[5] = { 'T', 'e', 's', 't', '\n' }; + // Send contents of uartBuffer + uartSend((uint8_t *)uartBuffer, 5); + @endcode + +*/ +/**************************************************************************/ +void uartSend (uint8_t *bufferPtr, uint32_t length) +{ + while (length != 0) + { + /* THRE status, contain valid data */ + while ( !(UART_U0LSR & UART_U0LSR_THRE) ); + UART_U0THR = *bufferPtr; + + bufferPtr++; + length--; + } + + return; +} + +/**************************************************************************/ +/*! + @brief Sends a single byte over UART. + + @param[in] byte + Byte value to send + + @section Example + + @code + // Send 0xFF over UART + uartSendByte(0xFF); + // Send 'B' over UART (note single quotes) + uartSendByte('B'); + @endcode + +*/ +/**************************************************************************/ +void uartSendByte (uint8_t byte) +{ + /* THRE status, contain valid data */ + while ( !(UART_U0LSR & UART_U0LSR_THRE) ); + UART_U0THR = byte; + + return; +} + + + diff --git a/core/uart/uart.h b/core/uart/uart.h new file mode 100644 index 0000000..928b6ce --- /dev/null +++ b/core/uart/uart.h @@ -0,0 +1,78 @@ +/**************************************************************************/ +/*! + @file uart.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __UART_H__ +#define __UART_H__ + +#include "projectconfig.h" + +// Buffer used for circular fifo +typedef struct _uart_buffer_t +{ + uint8_t ep_dir; + volatile uint8_t len; + volatile uint8_t wr_ptr; + volatile uint8_t rd_ptr; + uint8_t buf[CFG_UART_BUFSIZE]; +} uart_buffer_t; + +// UART Protocol control block +typedef struct _uart_pcb_t +{ + BOOL initialised; + uint32_t baudrate; + uint32_t status; + uint32_t pending_tx_data; + uart_buffer_t rxfifo; +} uart_pcb_t; + +void UART_IRQHandler(void); +uart_pcb_t *uartGetPCB(); +void uartInit(uint32_t Baudrate); +void uartSend(uint8_t *BufferPtr, uint32_t Length); +void uartSendByte (uint8_t byte); + +// Rx Buffer access control +void uartRxBufferInit(); +uint8_t uartRxBufferRead(); +void uartRxBufferWrite(uint8_t data); +void uartRxBufferClearFIFO(); +uint8_t uartRxBufferDataPending(); +bool uartRxBufferReadArray(byte_t* rx, size_t* len); + +#endif diff --git a/core/uart/uart_buf.c b/core/uart/uart_buf.c new file mode 100644 index 0000000..f51733e --- /dev/null +++ b/core/uart/uart_buf.c @@ -0,0 +1,149 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file uart_buf.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include "uart.h" + +/**************************************************************************/ +/*! + Initialises the RX FIFO buffer +*/ +/**************************************************************************/ +void uartRxBufferInit() +{ + uart_pcb_t *pcb = uartGetPCB(); + pcb->rxfifo.len = 0; +} + +/**************************************************************************/ +/*! + Read one byte out of the RX buffer. This function will return the byte + located at the array index of the read pointer, and then increment the + read pointer index. If the read pointer exceeds the maximum buffer + size, it will roll over to zero. +*/ +/**************************************************************************/ +uint8_t uartRxBufferRead() +{ + uart_pcb_t *pcb = uartGetPCB(); + uint8_t data; + + data = pcb->rxfifo.buf[pcb->rxfifo.rd_ptr]; + pcb->rxfifo.rd_ptr = (pcb->rxfifo.rd_ptr + 1) % CFG_UART_BUFSIZE; + pcb->rxfifo.len--; + return data; +} + +/**************************************************************************/ +/*! + Read byte array from uart + */ +/**************************************************************************/ +bool uartRxBufferReadArray(byte_t* rx, size_t* len) +{ + uart_pcb_t *pcb = uartGetPCB(); + *len = 0; + + while(pcb->rxfifo.len != 0) + { + (*rx) = uartRxBufferRead(); + (*len)++; + rx++; + } + + return (*len != 0); +} + +/**************************************************************************/ +/*! + Write one byte into the RX buffer. This function will write one + byte into the array index specified by the write pointer and increment + the write index. If the write index exceeds the max buffer size, then it + will roll over to zero. +*/ +/**************************************************************************/ +void uartRxBufferWrite(uint8_t data) +{ + uart_pcb_t *pcb = uartGetPCB(); + + pcb->rxfifo.buf[pcb->rxfifo.wr_ptr] = data; + pcb->rxfifo.wr_ptr = (pcb->rxfifo.wr_ptr + 1) % CFG_UART_BUFSIZE; + pcb->rxfifo.len++; +} + +/**************************************************************************/ +/*! + Clear the fifo read and write pointers and set the length to zero. +*/ +/**************************************************************************/ +void uartRxBufferClearFIFO() +{ + uart_pcb_t *pcb = uartGetPCB(); + + pcb->rxfifo.rd_ptr = 0; + pcb->rxfifo.wr_ptr = 0; + pcb->rxfifo.len = 0; +} + +/**************************************************************************/ +/*! + Check whether there is any data pending on the RX buffer. +*/ +/**************************************************************************/ +uint8_t uartRxBufferDataPending() +{ + uart_pcb_t *pcb = uartGetPCB(); + + if (pcb->rxfifo.len != 0) + { + return 1; + } + + return 0; +} diff --git a/core/usbcdc/cdc.h b/core/usbcdc/cdc.h new file mode 100644 index 0000000..f7af7d3 --- /dev/null +++ b/core/usbcdc/cdc.h @@ -0,0 +1,236 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: CDC.h + * Purpose: USB Communication Device Class Definitions + * Version: V1.00 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_H +#define __CDC_H + +/*---------------------------------------------------------------------------- + * Definitions based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ +// Communication device class specification version 1.10 +#define CDC_V1_10 0x0110 + +// Communication interface class code +// (usbcdc11.pdf, 4.2, Table 15) +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +// Communication interface class subclass codes +// (usbcdc11.pdf, 4.3, Table 16) +#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_TELEPHONE_CONTROL_MODEL 0x03 +#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04 +#define CDC_CAPI_CONTROL_MODEL 0x05 +#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06 +#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07 + +// Communication interface class control protocol codes +// (usbcdc11.pdf, 4.4, Table 17) +#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01 + +// Data interface class code +// (usbcdc11.pdf, 4.5, Table 18) +#define CDC_DATA_INTERFACE_CLASS 0x0A + +// Data interface class protocol codes +// (usbcdc11.pdf, 4.7, Table 19) +#define CDC_PROTOCOL_ISDN_BRI 0x30 +#define CDC_PROTOCOL_HDLC 0x31 +#define CDC_PROTOCOL_TRANSPARENT 0x32 +#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50 +#define CDC_PROTOCOL_Q921_DATA_LINK 0x51 +#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52 +#define CDC_PROTOCOL_V42 0x90 +#define CDC_PROTOCOL_EURO_ISDN 0x91 +#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92 +#define CDC_PROTOCOL_CAPI 0x93 +#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD +#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE + +// Type values for bDescriptorType field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 24) +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 + +// Type values for bDescriptorSubtype field of functional descriptors +// (usbcdc11.pdf, 5.2.3, Table 25) +#define CDC_HEADER 0x00 +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_DIRECT_LINE_MANAGEMENT 0x03 +#define CDC_TELEPHONE_RINGER 0x04 +#define CDC_REPORTING_CAPABILITIES 0x05 +#define CDC_UNION 0x06 +#define CDC_COUNTRY_SELECTION 0x07 +#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08 +#define CDC_USB_TERMINAL 0x09 +#define CDC_NETWORK_CHANNEL 0x0A +#define CDC_PROTOCOL_UNIT 0x0B +#define CDC_EXTENSION_UNIT 0x0C +#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D +#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E +#define CDC_ETHERNET_NETWORKING 0x0F +#define CDC_ATM_NETWORKING 0x10 + +// CDC class-specific request codes +// (usbcdc11.pdf, 6.2, Table 46) +// see Table 45 for info about the specific requests. +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_AUX_LINE_STATE 0x10 +#define CDC_SET_HOOK_STATE 0x11 +#define CDC_PULSE_SETUP 0x12 +#define CDC_SEND_PULSE 0x13 +#define CDC_SET_PULSE_TIME 0x14 +#define CDC_RING_AUX_JACK 0x15 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 +#define CDC_SET_RINGER_PARMS 0x30 +#define CDC_GET_RINGER_PARMS 0x31 +#define CDC_SET_OPERATION_PARMS 0x32 +#define CDC_GET_OPERATION_PARMS 0x33 +#define CDC_SET_LINE_PARMS 0x34 +#define CDC_GET_LINE_PARMS 0x35 +#define CDC_DIAL_DIGITS 0x36 +#define CDC_SET_UNIT_PARAMETER 0x37 +#define CDC_GET_UNIT_PARAMETER 0x38 +#define CDC_CLEAR_UNIT_PARAMETER 0x39 +#define CDC_GET_PROFILE 0x3A +#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define CDC_SET_ETHERNET_PMP_FILTER 0x41 +#define CDC_GET_ETHERNET_PMP_FILTER 0x42 +#define CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define CDC_GET_ETHERNET_STATISTIC 0x44 +#define CDC_SET_ATM_DATA_FORMAT 0x50 +#define CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define CDC_SET_ATM_DEFAULT_VC 0x52 +#define CDC_GET_ATM_VC_STATISTICS 0x53 + +// Communication feature selector codes +// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) +#define CDC_ABSTRACT_STATE 0x01 +#define CDC_COUNTRY_SETTING 0x02 + +// Feature Status returned for ABSTRACT_STATE Selector +// (usbcdc11.pdf, 6.2.3, Table 48) +#define CDC_IDLE_SETTING (1 << 0) +#define CDC_DATA_MULTPLEXED_STATE (1 << 1) + + +// Control signal bitmap values for the SetControlLineState request +// (usbcdc11.pdf, 6.2.14, Table 51) +#define CDC_DTE_PRESENT (1 << 0) +#define CDC_ACTIVATE_CARRIER (1 << 1) + +// CDC class-specific notification codes +// (usbcdc11.pdf, 6.3, Table 68) +// see Table 67 for Info about class-specific notifications +#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00 +#define CDC_RESPONSE_AVAILABLE 0x01 +#define CDC_AUX_JACK_HOOK_STATE 0x08 +#define CDC_RING_DETECT 0x09 +#define CDC_NOTIFICATION_SERIAL_STATE 0x20 +#define CDC_CALL_STATE_CHANGE 0x28 +#define CDC_LINE_STATE_CHANGE 0x29 +#define CDC_CONNECTION_SPEED_CHANGE 0x2A + +// UART state bitmap values (Serial state notification). +// (usbcdc11.pdf, 6.3.5, Table 69) +#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred +#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred +#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred +#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection +#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection +#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier +#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier + + +/*---------------------------------------------------------------------------- + * Structures based on usbcdc11.pdf (www.usb.org) + *---------------------------------------------------------------------------*/ + +// Header functional descriptor +// (usbcdc11.pdf, 5.2.3.1) +// This header must precede any list of class-specific descriptors. +typedef struct _CDC_HEADER_DESCRIPTOR{ + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // Header functional descriptor subtype + uint16_t bcdCDC; // USB CDC specification release version +} __attribute__((packed)) CDC_HEADER_DESCRIPTOR; + +//Call management functional descriptor +// (usbcdc11.pdf, 5.2.3.2) +// Describes the processing of calls for the communication class interface. +typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // call management functional descriptor subtype + uint8_t bmCapabilities; // capabilities that this configuration supports + uint8_t bDataInterface; // interface number of the data class interface used for call management (optional) +} __attribute__((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR; + +// Abstract control management functional descriptor +// (usbcdc11.pdf, 5.2.3.3) +// Describes the command supported by the communication interface class with the Abstract Control Model subclass code. +typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype + uint8_t bmCapabilities; // capabilities supported by this configuration +} __attribute__((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR; + +// Union functional descriptors +// (usbcdc11.pdf, 5.2.3.8) +// Describes the relationship between a group of interfaces that can be considered to form a functional unit. +typedef struct _CDC_UNION_DESCRIPTOR { + uint8_t bFunctionLength; // size of this descriptor in bytes + uint8_t bDescriptorType; // CS_INTERFACE descriptor type + uint8_t bDescriptorSubtype; // union functional descriptor subtype + uint8_t bMasterInterface; // interface number designated as master +} __attribute__((packed)) CDC_UNION_DESCRIPTOR; + +// Union functional descriptors with one slave interface +// (usbcdc11.pdf, 5.2.3.8) +typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR { + CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor + uint8_t bSlaveInterfaces[1]; // Slave interface 0 +} __attribute__((packed)) CDC_UNION_1SLAVE_DESCRIPTOR; + +// Line coding structure +// Format of the data returned when a GetLineCoding request is received +// (usbcdc11.pdf, 6.2.13) +typedef struct _CDC_LINE_CODING { + uint32_t dwDTERate; // Data terminal rate in bits per second + uint8_t bCharFormat; // Number of stop bits + uint8_t bParityType; // Parity bit type + uint8_t bDataBits; // Number of data bits +} __attribute__((packed)) CDC_LINE_CODING; + +// Notification header +// Data sent on the notification endpoint must follow this header. +// see USB_SETUP_PACKET in file usb.h +typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER; + +#endif /* __CDC_H */ + diff --git a/core/usbcdc/cdc_buf.c b/core/usbcdc/cdc_buf.c new file mode 100644 index 0000000..2a7c1d5 --- /dev/null +++ b/core/usbcdc/cdc_buf.c @@ -0,0 +1,161 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ + +/**************************************************************************/ +/*! + @file cdc_buf.c + @author Christopher Wang (Freaklabs) + Modified by: K. Townsend (microBuilder.eu) + @date 19 May 2010 + + Original code taken from the FreakUSB Open Source USB Device Stack + http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html + + If it works well, you can thank Akiba at Freaklabs. If it fails + miserably, you can blame me (since parts of it it were rather + ungraciously modified). :-) + +*/ +/**************************************************************************/ + +#include "cdc_buf.h" + +static cdc_buffer_t cdcfifo; + +/**************************************************************************/ +/*! + Gets a pointer to the fifo buffer +*/ +/**************************************************************************/ +cdc_buffer_t *cdcGetBuffer() +{ + return &cdcfifo; +} + +/**************************************************************************/ +/*! + Initialises the RX FIFO buffer +*/ +/**************************************************************************/ +void cdcBufferInit() +{ + cdcfifo.len = 0; +} + +/**************************************************************************/ +/*! + Read one byte out of the RX buffer. This function will return the byte + located at the array index of the read pointer, and then increment the + read pointer index. If the read pointer exceeds the maximum buffer + size, it will roll over to zero. +*/ +/**************************************************************************/ +uint8_t cdcBufferRead() +{ + uint8_t data; + + data = cdcfifo.buf[cdcfifo.rd_ptr]; + cdcfifo.rd_ptr = (cdcfifo.rd_ptr + 1) % CFG_USBCDC_BUFFERSIZE; + cdcfifo.len--; + return data; +} + +/**************************************************************************/ +/*! + Reads x bytes from cdc buffer + */ +/**************************************************************************/ +uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len) +{ + uint32_t counter, actual; + counter = actual = 0; + + while(counter != len) + { + // Make sure we don't exceed buffer limits + if (cdcfifo.len > 0) + { + buf[counter] = cdcBufferRead(); + actual++; + counter++; + } + else + { + return actual; + } + } + + return actual; +} + +/**************************************************************************/ +/*! + Write one byte into the RX buffer. This function will write one + byte into the array index specified by the write pointer and increment + the write index. If the write index exceeds the max buffer size, then it + will roll over to zero. +*/ +/**************************************************************************/ +void cdcBufferWrite(uint8_t data) +{ + cdcfifo.buf[cdcfifo.wr_ptr] = data; + cdcfifo.wr_ptr = (cdcfifo.wr_ptr + 1) % CFG_USBCDC_BUFFERSIZE; + cdcfifo.len++; +} + +/**************************************************************************/ +/*! + Clear the fifo read and write pointers and set the length to zero. +*/ +/**************************************************************************/ +void cdcBufferClearFIFO() +{ + cdcfifo.rd_ptr = 0; + cdcfifo.wr_ptr = 0; + cdcfifo.len = 0; +} + +/**************************************************************************/ +/*! + Check whether there is any data pending on the RX buffer. +*/ +/**************************************************************************/ +uint8_t cdcBufferDataPending() +{ + if (cdcfifo.len != 0) + { + return 1; + } + + return 0; +} diff --git a/core/usbcdc/cdc_buf.h b/core/usbcdc/cdc_buf.h new file mode 100644 index 0000000..c5cdfad --- /dev/null +++ b/core/usbcdc/cdc_buf.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------- + * Name: cdc_buf.h + * Purpose: usb cdc buffer handling + * Version: V1.00 + *---------------------------------------------------------------------------*/ + +#ifndef __CDC_BUF_H__ +#define __CDC_BUF_H__ + +#include "projectconfig.h" + +// Buffer used for circular fifo +typedef struct _cdc_buffer_t +{ + volatile uint8_t len; + volatile uint8_t wr_ptr; + volatile uint8_t rd_ptr; + uint8_t buf[CFG_USBCDC_BUFFERSIZE]; +} cdc_buffer_t; + +cdc_buffer_t * cdcGetBuffer(); +void cdcBufferInit(); +uint8_t cdcBufferRead(); +uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len); +void cdcBufferWrite(uint8_t data); +void cdcBufferClearFIFO(); +uint8_t cdcBufferDataPending(); + +#endif diff --git a/core/usbcdc/cdcuser.c b/core/usbcdc/cdcuser.c new file mode 100644 index 0000000..d553f47 --- /dev/null +++ b/core/usbcdc/cdcuser.c @@ -0,0 +1,351 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.c + * Purpose: USB Communication Device Class User module + * Version: V1.10 + *---------------------------------------------------------------------------- +* This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#include "projectconfig.h" + +#include "usb.h" +#include "usbhw.h" +#include "usbcfg.h" +#include "usbcore.h" +#include "cdc.h" +#include "cdcuser.h" +#include "cdc_buf.h" + +// unsigned char BulkBufIn [64]; // Buffer to store USB IN packet +unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet +unsigned char NotificationBuf [10]; + +CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8}; +unsigned short CDC_SerialState = 0x0000; +unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty + +/*---------------------------------------------------------------------------- + We need a buffer for incoming data on USB port because USB receives + much faster than UART transmits + *---------------------------------------------------------------------------*/ +/* Buffer masks */ +#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2) + // large enough for file transfer +#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul) + +/* Buffer read / write macros */ +#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0) +#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn)) +#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++]) +#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx) +#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1) +#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx)) + + +// CDC output buffer +typedef struct __CDC_BUF_T +{ + unsigned char data[CDC_BUF_SIZE]; + volatile unsigned int wrIdx; + volatile unsigned int rdIdx; +} CDC_BUF_T; + +CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data + +/*---------------------------------------------------------------------------- + read data from CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_RdOutBuf (char *buffer, const int *length) +{ + int bytesToRead, bytesRead; + + /* Read *length bytes, block if *bytes are not avaialable */ + bytesToRead = *length; + bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length); + bytesRead = bytesToRead; + + + // ... add code to check for underrun + + while (bytesToRead--) { + *buffer++ = CDC_BUF_RD(CDC_OutBuf); + } + return (bytesRead); +} + +/*---------------------------------------------------------------------------- + write data to CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_WrOutBuf (const char *buffer, int *length) +{ + int bytesToWrite, bytesWritten; + + // Write *length bytes + bytesToWrite = *length; + bytesWritten = bytesToWrite; + + + // ... add code to check for overwrite + + while (bytesToWrite) { + CDC_BUF_WR(CDC_OutBuf, *buffer++); // Copy Data to buffer + bytesToWrite--; + } + + return (bytesWritten); +} + +/*---------------------------------------------------------------------------- + check if character(s) are available at CDC_OutBuf + *---------------------------------------------------------------------------*/ +int CDC_OutBufAvailChar (int *availChar) +{ + *availChar = CDC_BUF_COUNT(CDC_OutBuf); + + return (0); +} +/* end Buffer handling */ + + +/*---------------------------------------------------------------------------- + CDC Initialisation + Initializes the data structures and serial port + Parameters: None + Return Value: None + *---------------------------------------------------------------------------*/ +void CDC_Init (void) +{ + CDC_DepInEmpty = 1; + CDC_SerialState = CDC_GetSerialState(); + + CDC_BUF_RESET(CDC_OutBuf); + + // Initialise the CDC buffer. This is required to buffer outgoing + // data (MCU to PC) since data can only be sent 64 bytes per frame + // with at least 1ms between frames. To see how the buffer is used, + // see 'puts' in systeminit.c + cdcBufferInit(); +} + + +/*---------------------------------------------------------------------------- + CDC SendEncapsulatedCommand Request Callback + Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SendEncapsulatedCommand (void) +{ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetEncapsulatedResponse Request Callback + Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetEncapsulatedResponse (void) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetCommFeature Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetCommFeature Request Callback + Called automatically on CDC Get_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC ClearCommFeature Request Callback + Called automatically on CDC CLEAR_COMM_FATURE Request + Parameters: FeatureSelector + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector) +{ + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetLineCoding Request Callback + Called automatically on CDC SET_LINE_CODING Request + Parameters: none (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetLineCoding (void) +{ + CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0) + | (EP0Buf[1] << 8) + | (EP0Buf[2] << 16) + | (EP0Buf[3] << 24); + CDC_LineCoding.bCharFormat = EP0Buf[4]; + CDC_LineCoding.bParityType = EP0Buf[5]; + CDC_LineCoding.bDataBits = EP0Buf[6]; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC GetLineCoding Request Callback + Called automatically on CDC GET_LINE_CODING Request + Parameters: None (global SetupPacket and EP0Buf) + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_GetLineCoding (void) +{ + EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF; + EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF; + EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF; + EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF; + EP0Buf[4] = CDC_LineCoding.bCharFormat; + EP0Buf[5] = CDC_LineCoding.bParityType; + EP0Buf[6] = CDC_LineCoding.bDataBits; + + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SetControlLineState Request Callback + Called automatically on CDC SET_CONTROL_LINE_STATE Request + Parameters: ControlSignalBitmap + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) { + + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC SendBreak Request Callback + Called automatically on CDC Set_COMM_FATURE Request + Parameters: 0xFFFF start of Break + 0x0000 stop of Break + 0x#### Duration of Break + Return Value: TRUE - Success, FALSE - Error + *---------------------------------------------------------------------------*/ +uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) { + + /* ... add code to handle request */ + return (TRUE); +} + + +/*---------------------------------------------------------------------------- + CDC_BulkIn call on DataIn Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void CDC_BulkIn(void) +{ +// int numBytesRead, numBytesAvail; +// +// // ToDo: Modify BulkIn to send incoming data to USB +// +// ser_AvailChar (&numBytesAvail); +// +// // ... add code to check for overwrite +// +// numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail); +// +// // send over USB +// if (numBytesRead > 0) { +// USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead); +// } +// else { +// CDC_DepInEmpty = 1; +// } +// +// +} + + +/*---------------------------------------------------------------------------- + CDC_BulkOut call on DataOut Request + Parameters: none + Return Value: none + *---------------------------------------------------------------------------*/ +void CDC_BulkOut(void) +{ + int numBytesRead; + + // get data from USB into intermediate buffer + numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]); + + // ... add code to check for overwrite + + // store data in a buffer to transmit it over serial interface + CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead); +} + + +/*---------------------------------------------------------------------------- + Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69. + Parameters: none + Return Value: SerialState as defined in usbcdc11.pdf + *---------------------------------------------------------------------------*/ +unsigned short CDC_GetSerialState (void) +{ + CDC_SerialState = 0; + + return (CDC_SerialState); +} + + +/*---------------------------------------------------------------------------- + Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5. + *---------------------------------------------------------------------------*/ +void CDC_NotificationIn (void) +{ + NotificationBuf[0] = 0xA1; // bmRequestType + NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE) + NotificationBuf[2] = 0x00; // wValue + NotificationBuf[3] = 0x00; + NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first) + NotificationBuf[5] = 0x00; + NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first) + NotificationBuf[7] = 0x00; + NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first) + NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF; + + USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification +} diff --git a/core/usbcdc/cdcuser.h b/core/usbcdc/cdcuser.h new file mode 100644 index 0000000..55cd910 --- /dev/null +++ b/core/usbcdc/cdcuser.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: cdcuser.h + * Purpose: USB Communication Device Class User module Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __CDCUSER_H__ +#define __CDCUSER_H__ + +/* CDC buffer handling */ +extern int CDC_RdOutBuf (char *buffer, const int *length); +extern int CDC_WrOutBuf (const char *buffer, int *length); +extern int CDC_OutBufAvailChar (int *availChar); + + +/* CDC Data In/Out Endpoint Address */ +#define CDC_DEP_IN 0x83 +#define CDC_DEP_OUT 0x03 + +/* CDC Communication In Endpoint Address */ +#define CDC_CEP_IN 0x81 + +/* CDC Requests Callback Functions */ +extern uint32_t CDC_SendEncapsulatedCommand (void); +extern uint32_t CDC_GetEncapsulatedResponse (void); +extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector); +extern uint32_t CDC_GetLineCoding (void); +extern uint32_t CDC_SetLineCoding (void); +extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap); +extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak); + +/* CDC Bulk Callback Functions */ +extern void CDC_BulkIn (void); +extern void CDC_BulkOut (void); + +/* CDC Notification Callback Function */ +extern void CDC_NotificationIn (void); + +/* CDC Initialization Function */ +extern void CDC_Init (void); + +/* CDC prepare the SERAIAL_STATE */ +extern unsigned short CDC_GetSerialState (void); + +/* flow control */ +extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty + +#endif /* __CDCUSER_H__ */ + diff --git a/core/usbcdc/config.h b/core/usbcdc/config.h new file mode 100644 index 0000000..fcfee37 --- /dev/null +++ b/core/usbcdc/config.h @@ -0,0 +1,40 @@ +/***************************************************************************** + * config.h: config file for usbcdc example for NXP LPC13xx Family + * Microprocessors + * + * Copyright(C) 2008, NXP Semiconductor + * All rights reserved. + * + * History + * 2008.07.19 ver 1.00 Preliminary version, first Release + * +******************************************************************************/ + +/* +Overview: + This example shows how to use the USB driver to implement a CDC class USB peripheral. + To run this example, you must attach a USB cable to the board. See + the "Getting Started Guide" appendix for details. + +How to use: + Click the debug toolbar button. + Click the go button. + Plug the LPCXpresso's target side into a PC using a USB cable retrofit + or a 3rd party base board. + + * You should be able to see a new COM port on your PC. +*/ + +#include "projectconfig.h" + +#define USB_VENDOR_ID CFG_USB_VID // Vendor ID +#define USB_PROD_ID CFG_USB_PID // Product ID +#define USB_DEVICE 0x0100 // Device ID + +#define LED_PORT 0 // Port for led +#define LED_BIT 7 // Bit on port for led + + +/********************************************************************************* +** End Of File +*********************************************************************************/ diff --git a/core/usbcdc/usb.h b/core/usbcdc/usb.h new file mode 100644 index 0000000..6ba0aeb --- /dev/null +++ b/core/usbcdc/usb.h @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USB_H__ +#define __USB_H__ + + +typedef union { + uint16_t W; + struct { + uint8_t L; + uint8_t H; + } __attribute__((packed)) WB; +} __attribute__((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE { + struct _BM { + uint8_t Recipient : 5; + uint8_t Type : 2; + uint8_t Dir : 1; + } __attribute__((packed)) BM; + uint8_t B; +} __attribute__((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET { + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString/*[]*/; +} __attribute__((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR { + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__((packed)) USB_COMMON_DESCRIPTOR; + + +#endif /* __USB_H__ */ diff --git a/core/usbcdc/usbcfg.h b/core/usbcdc/usbcfg.h new file mode 100644 index 0000000..cad6c43 --- /dev/null +++ b/core/usbcdc/usbcfg.h @@ -0,0 +1,157 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcfg.h + * Purpose: USB Custom Configuration + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific support + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ + +#ifndef __USBCFG_H__ +#define __USBCFG_H__ + + +//*** <<< Use Configuration Wizard in Context Menu >>> *** + + +/* +// USB Configuration +// USB Power +// Default Power Setting +// <0=> Bus-powered +// <1=> Self-powered +// Max Number of Interfaces <1-256> +// Max Number of Endpoints <1-32> +// Max Endpoint 0 Packet Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// DMA Transfer +// Use DMA for selected Endpoints +// Endpoint 0 Out +// Endpoint 0 In +// Endpoint 1 Out +// Endpoint 1 In +// Endpoint 2 Out +// Endpoint 2 In +// Endpoint 3 Out +// Endpoint 3 In +// Endpoint 4 Out +// Endpoint 4 In +// +// +*/ + +#define USB_POWER 0 +#define USB_IF_NUM 1 +#define USB_LOGIC_EP_NUM 5 +#define USB_EP_NUM 10 +#define USB_MAX_PACKET0 64 + +/* +// USB Event Handlers +// Device Events +// Power Event +// Reset Event +// Suspend Event +// Resume Event +// Remote Wakeup Event +// Start of Frame Event +// Error Event +// +// Endpoint Events +// Endpoint 0 Event +// Endpoint 1 Event +// Endpoint 2 Event +// Endpoint 3 Event +// Endpoint 4 Event +// Endpoint 5 Event +// Endpoint 6 Event +// Endpoint 7 Event +// Endpoint 8 Event +// Endpoint 9 Event +// Endpoint 10 Event +// Endpoint 11 Event +// Endpoint 12 Event +// Endpoint 13 Event +// Endpoint 14 Event +// Endpoint 15 Event +// +// USB Core Events +// Set Configuration Event +// Set Interface Event +// Set/Clear Feature Event +// +// +*/ + +#define USB_POWER_EVENT 0 +#define USB_RESET_EVENT 1 +#define USB_SUSPEND_EVENT 1 +#define USB_RESUME_EVENT 1 +#define USB_WAKEUP_EVENT 0 +#define USB_SOF_EVENT 1 +#define USB_ERROR_EVENT 0 +#define USB_EP_EVENT 0x000B +#define USB_CONFIGURE_EVENT 1 +#define USB_INTERFACE_EVENT 0 +#define USB_FEATURE_EVENT 0 + + +/* +// USB Class Support +// enables USB Class specific Requests +// Human Interface Device (HID) +// Interface Number <0-255> +// +// Mass Storage +// Interface Number <0-255> +// +// Audio Device +// Control Interface Number <0-255> +// Streaming Interface 1 Number <0-255> +// Streaming Interface 2 Number <0-255> +// +// Communication Device +// Control Interface Number <0-255> +// Bulk Interface Number <0-255> +// Max Communication Device Buffer Size +// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes +// +// +*/ + +#define USB_CLASS 1 +#define USB_HID 0 +#define USB_HID_IF_NUM 0 +#define USB_MSC 0 +#define USB_MSC_IF_NUM 0 +#define USB_AUDIO 0 +#define USB_ADC_CIF_NUM 0 +#define USB_ADC_SIF1_NUM 1 +#define USB_ADC_SIF2_NUM 2 +#define USB_CDC 1 +#define USB_CDC_CIF_NUM 0 +#define USB_CDC_DIF_NUM 1 +#define USB_CDC_BUFSIZE CFG_USBCDC_BUFSIZE + +/* +// USB Vendor Support +// enables USB Vendor specific Requests +// +*/ +#define USB_VENDOR 0 + + +#endif /* __USBCFG_H__ */ diff --git a/core/usbcdc/usbcore.c b/core/usbcdc/usbcore.c new file mode 100644 index 0000000..fe09bbd --- /dev/null +++ b/core/usbcdc/usbcore.c @@ -0,0 +1,1058 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.c + * Purpose: USB Core Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific requests + * Changed string descriptor handling + * Reworked Endpoint0 + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "projectconfig.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbdesc.h" +#include "usbuser.h" + +#if (USB_CLASS) + +#if (USB_AUDIO) +#include "audio.h" +#include "adcuser.h" +#endif + +#if (USB_HID) +#include "hid.h" +#include "hiduser.h" +#endif + +#if (USB_MSC) +#include "msc.h" +#include "mscuser.h" +extern MSC_CSW CSW; +#endif + +#if (USB_CDC) +#include "cdc.h" +#include "cdcuser.h" +#endif + +#endif + +#if (USB_VENDOR) +#include "vendor.h" +#endif + +uint16_t USB_DeviceStatus; +uint8_t USB_DeviceAddress; +volatile uint8_t USB_Configuration; +uint32_t USB_EndPointMask; +uint32_t USB_EndPointHalt; +uint32_t USB_EndPointStall; /* EP must stay stalled */ +uint8_t USB_NumInterfaces; +uint8_t USB_AltSetting[USB_IF_NUM]; + +uint8_t EP0Buf[USB_MAX_PACKET0]; + + +USB_EP_DATA EP0Data; + +USB_SETUP_PACKET SetupPacket; + + +/* + * Reset USB Core + * Parameters: None + * Return Value: None + */ + +void USB_ResetCore (void) { + + USB_DeviceStatus = USB_POWER; + USB_DeviceAddress = 0; + USB_Configuration = 0; + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; +} + + +/* + * USB Request - Setup Stage + * Parameters: None (global SetupPacket) + * Return Value: None + */ + +void USB_SetupStage (void) { + USB_ReadEP(0x00, (uint8_t *)&SetupPacket); +} + + +/* + * USB Request - Data In Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataInStage (void) { + uint32_t cnt; + + if (EP0Data.Count > USB_MAX_PACKET0) { + cnt = USB_MAX_PACKET0; + } else { + cnt = EP0Data.Count; + } + cnt = USB_WriteEP(0x80, EP0Data.pData, cnt); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Data Out Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataOutStage (void) { + uint32_t cnt; + + cnt = USB_ReadEP(0x00, EP0Data.pData); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Status In Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusInStage (void) { + USB_WriteEP(0x80, NULL, 0); +} + + +/* + * USB Request - Status Out Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusOutStage (void) { + USB_ReadEP(0x00, EP0Buf); +} + + +/* + * Get Status USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetStatus (void) { + uint32_t n, m; + uint16_t* ep0 = (uint16_t __attribute__((packed)) *)EP0Buf; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + EP0Data.pData = (uint8_t *)&USB_DeviceStatus; + break; + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + *ep0 = 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) { + *ep0 = (USB_EndPointHalt & m) ? 1 : 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set/Clear Feature USB Request + * Parameters: sc: 0 - Clear, 1 - Set + * (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetClrFeature (uint32_t sc) { + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) { + if (sc) { + USB_WakeUpCfg(TRUE); + USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; + } else { + USB_WakeUpCfg(FALSE); + USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; + } + } else { + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + return (FALSE); + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) { + if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) { + if (sc) { + USB_SetStallEP(n); + USB_EndPointHalt |= m; + } else { + if ((USB_EndPointStall & m) != 0) { + return (TRUE); + } + USB_ClrStallEP(n); +#if (USB_MSC) + if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0)) { + /* Compliance Test: rewrite CSW after unstall */ + if (CSW.dSignature == MSC_CSW_Signature) { + USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW)); + } + } +#endif + USB_EndPointHalt &= ~m; + } + } else { + return (FALSE); + } + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Address USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetAddress (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Descriptor USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetDescriptor (void) { + uint8_t *pD; + uint32_t len, n; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + switch (SetupPacket.wValue.WB.H) { + case USB_DEVICE_DESCRIPTOR_TYPE: + EP0Data.pData = (uint8_t *)USB_DeviceDescriptor; + len = USB_DEVICE_DESC_SIZE; + break; + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_ConfigDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + } + } + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + break; + case USB_STRING_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_StringDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_STRING_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_STRING_DESCRIPTOR *)pD)->bLength; + } + } + if (((USB_STRING_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; + break; + default: + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + switch (SetupPacket.wValue.WB.H) { +#if USB_HID + case HID_HID_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)USB_ConfigDescriptor + HID_DESC_OFFSET; + len = HID_DESC_SIZE; + break; + case HID_REPORT_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)HID_ReportDescriptor; + len = HID_ReportDescSize; + break; + case HID_PHYSICAL_DESCRIPTOR_TYPE: + return (FALSE); /* HID Physical Descriptor is not supported */ +#endif + default: + return (FALSE); + } + break; + default: + return (FALSE); + } + + if (EP0Data.Count > len) { + EP0Data.Count = len; + } + + return (TRUE); +} + +/* + * Get Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetConfiguration (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + // Added cast to avoid warnings due to USB_Configuration being volatile (KTownsend) + EP0Data.pData = (uint8_t *)&USB_Configuration; + break; + default: + return (FALSE); + } + return (TRUE); +} + +/* + * Set Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetConfiguration (void) { + USB_COMMON_DESCRIPTOR *pD; + uint32_t alt = 0; + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + + if (SetupPacket.wValue.WB.L) { + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == SetupPacket.wValue.WB.L) { + USB_Configuration = SetupPacket.wValue.WB.L; + USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces; + for (n = 0; n < USB_IF_NUM; n++) { + USB_AltSetting[n] = 0; + } + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall= 0x00000000; + USB_Configure(TRUE); + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_POWERED_MASK) { + USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; + } else { + USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; + } + } else { + UsbAddPtr((void **)&pD, ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (alt == 0) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + USB_EndPointMask |= m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + } + break; + } + UsbAddPtr((void **)&pD, pD->bLength); + } + } + else { + USB_Configuration = 0; + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure(FALSE); + } + + if (USB_Configuration != SetupPacket.wValue.WB.L) { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqGetInterface (void) { + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +static inline uint32_t USB_ReqSetInterface (void) { + USB_COMMON_DESCRIPTOR *pD; + uint32_t ifn = 0, alt = 0, old = 0, msk = 0; + uint32_t n, m; + uint32_t set; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if (USB_Configuration == 0) return (FALSE); + set = FALSE; + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue != USB_Configuration) { + UsbAddPtr((void **)&pD, ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength); + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + ifn = ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber; + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + msk = 0; + if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L)) { + set = TRUE; + old = USB_AltSetting[ifn]; + USB_AltSetting[ifn] = (uint8_t)alt; + } + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (ifn == SetupPacket.wIndex.WB.L) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (alt == SetupPacket.wValue.WB.L) { + USB_EndPointMask |= m; + USB_EndPointHalt &= ~m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + msk |= m; + } + else if ((alt == old) && ((msk & m) == 0)) { + USB_EndPointMask &= ~m; + USB_EndPointHalt &= ~m; + USB_DisableEP(n); + } + } + break; + } + UsbAddPtr((void **)&pD, pD->bLength); + } + break; + default: + return (FALSE); + } + + return (set); +} + +/* + * USB Endpoint 0 Event Callback + * Parameters: event + * Return Value: none + */ + +void USB_EndPoint0 (uint32_t event) { + + switch (event) { + case USB_EVT_SETUP: + USB_SetupStage(); + USB_DirCtrlEP(SetupPacket.bmRequestType.BM.Dir); + EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + switch (SetupPacket.bRequest) { + case USB_REQUEST_GET_STATUS: + if (!USB_ReqGetStatus()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_CLEAR_FEATURE: + if (!USB_ReqSetClrFeature(0)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_FEATURE: + if (!USB_ReqSetClrFeature(1)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_ADDRESS: + if (!USB_ReqSetAddress()) { + goto stall_i; + } + USB_StatusInStage(); + break; + + case USB_REQUEST_GET_DESCRIPTOR: + if (!USB_ReqGetDescriptor()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_DESCRIPTOR: +/*stall_o:*/ USB_SetStallEP(0x00); /* not supported */ + EP0Data.Count = 0; + break; + + case USB_REQUEST_GET_CONFIGURATION: + if (!USB_ReqGetConfiguration()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_CONFIGURATION: + if (!USB_ReqSetConfiguration()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_CONFIGURE_EVENT + USB_Configure_Event(); +#endif + break; + + case USB_REQUEST_GET_INTERFACE: + if (!USB_ReqGetInterface()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_INTERFACE: + if (!USB_ReqSetInterface()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_INTERFACE_EVENT + USB_Interface_Event(); +#endif + break; + + default: + goto stall_i; + } + break; /* end case REQUEST_STANDARD */ + +#if USB_CLASS + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_GET_REPORT: + if (HID_GetReport()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_REPORT: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + case HID_REQUEST_GET_IDLE: + if (HID_GetIdle()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_IDLE: + if (HID_SetIdle()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case HID_REQUEST_GET_PROTOCOL: + if (HID_GetProtocol()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_PROTOCOL: + if (HID_SetProtocol()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_MSC + if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case MSC_REQUEST_RESET: + if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */ + (SetupPacket.wLength == 0)) { + if (MSC_Reset()) { + USB_StatusInStage(); + goto setup_class_ok; + } + } + break; + case MSC_REQUEST_GET_MAX_LUN: + if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */ + (SetupPacket.wLength == 1)) { + if (MSC_GetMaxLUN()) { + EP0Data.pData = EP0Buf; + USB_DataInStage(); + goto setup_class_ok; + } + } + break; + } + } +#endif /* USB_MSC */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_IF_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_ENCAPSULATED_RESPONSE: + if (CDC_GetEncapsulatedResponse()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_COMM_FEATURE: + if (CDC_GetCommFeature(SetupPacket.wValue.W)) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_CLEAR_COMM_FEATURE: + if (CDC_ClearCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SET_LINE_CODING: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_LINE_CODING: + if (CDC_GetLineCoding()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_CONTROL_LINE_STATE: + if (CDC_SetControlLineState(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SEND_BREAK: + if (CDC_SendBreak(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; /* not supported */ + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_EP_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +setup_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + if (SetupPacket.wLength) { + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); + } + } else { + USB_StatusInStage(); + } + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: +stall_i: USB_SetStallEP(0x80); + EP0Data.Count = 0; + break; + } + break; /* end case USB_EVT_SETUP */ + + case USB_EVT_OUT: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE) { + if (EP0Data.Count) { /* still data to receive ? */ + USB_DataOutStage(); /* receive data */ + if (EP0Data.Count == 0) { /* data complete ? */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + goto stall_i; /* not supported */ + +#if (USB_CLASS) + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_SET_REPORT: + if (HID_SetReport()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_IF_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + if (CDC_SendEncapsulatedCommand()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + if (CDC_SetCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_LINE_CODING: + if (CDC_SetLineCoding()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_EP_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +out_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + USB_StatusInStage(); + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + goto stall_i; + } + } + } + } else { + USB_StatusOutStage(); /* receive Acknowledge */ + } + break; /* end case USB_EVT_OUT */ + + case USB_EVT_IN : + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); /* send data */ + } else { + if (USB_DeviceAddress & 0x80) { + USB_DeviceAddress &= 0x7F; + USB_SetAddress(USB_DeviceAddress); + } + } + break; /* end case USB_EVT_IN */ + + case USB_EVT_OUT_STALL: + USB_ClrStallEP(0x00); + break; + + case USB_EVT_IN_STALL: + USB_ClrStallEP(0x80); + break; + + } +} diff --git a/core/usbcdc/usbcore.h b/core/usbcdc/usbcore.h new file mode 100644 index 0000000..5098be0 --- /dev/null +++ b/core/usbcdc/usbcore.h @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.h + * Purpose: USB Core Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + +#include "usbcfg.h" + +/* USB Endpoint Data Structure */ +typedef struct _USB_EP_DATA { + uint8_t *pData; + uint16_t Count; +} USB_EP_DATA; + +/* USB Core Global Variables */ +extern uint16_t USB_DeviceStatus; +extern uint8_t USB_DeviceAddress; +volatile extern uint8_t USB_Configuration; +extern uint32_t USB_EndPointMask; +extern uint32_t USB_EndPointHalt; +extern uint32_t USB_EndPointStall; +extern uint8_t USB_AltSetting[USB_IF_NUM]; + + +/* USB Endpoint 0 Buffer */ +extern uint8_t EP0Buf[USB_MAX_PACKET0]; + +/* USB Endpoint 0 Data Info */ +extern USB_EP_DATA EP0Data; + +/* USB Setup Packet */ +extern USB_SETUP_PACKET SetupPacket; + +/* USB Core Functions */ +extern void USB_ResetCore (void); + +/* Newer C compilers make it really difficult to add + * an integer to a pointer */ +static inline void UsbAddPtr(void **vpptr, uint32_t n); + +/* + * Add a number of bytes to a pointer's address + * Harder than you might think. Some compilers say: + * Expected an lvalue -- Assignment expects its first operand to be + * an lvalue. Please note that a cast removes the lvaluedness of an + * expression. + * + * vpptr = void pointer to pointer + * n = number of bytes to add to pointer + * Call looks like: AddPtr((void **)&myPointer, 8); + */ +static inline void UsbAddPtr(void **vpptr, uint32_t n) +{ + /* Declare a pointer to a pointer to a byte. Only a byte pointer + * can be incremented by a number of bytes. Other pointers will + * increment by a multiple of what they point to. + */ + uint8_t **bpptr; + + /* Convert our void pointer to a pointer to a byte pointer to a pointer */ + bpptr = (uint8_t **)vpptr; + + /* Add 'n' bytes to our pointer value */ + (*bpptr) += n; +} + + + + + + + +#endif /* __USBCORE_H__ */ diff --git a/core/usbcdc/usbdesc.c b/core/usbcdc/usbdesc.c new file mode 100644 index 0000000..6642e60 --- /dev/null +++ b/core/usbcdc/usbdesc.c @@ -0,0 +1,202 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.c + * Purpose: USB Descriptors + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Changed string descriptor handling + * V1.00 Initial Version + *---------------------------------------------------------------------------*/ +#include "projectconfig.h" +#include "usb.h" +#include "cdc.h" +#include "usbcfg.h" +#include "usbdesc.h" +#include "config.h" + + +/* USB Standard Device Descriptor */ +const uint8_t USB_DeviceDescriptor[] = { + USB_DEVICE_DESC_SIZE, /* bLength */ + USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0200), /* 2.0 */ /* bcdUSB */ + USB_DEVICE_CLASS_COMMUNICATIONS, /* bDeviceClass CDC*/ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_PACKET0, /* bMaxPacketSize0 */ + WBVAL(USB_VENDOR_ID), /* idVendor */ + WBVAL(USB_PROD_ID), /* idProduct */ + WBVAL(USB_DEVICE), /* 1.00 */ /* bcdDevice */ + 0x01, /* iManufacturer */ + 0x02, /* iProduct */ + 0x03, /* iSerialNumber */ + 0x01 /* bNumConfigurations: one possible configuration*/ +}; + +/* USB Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +const uint8_t USB_ConfigDescriptor[] = { +/* Configuration 1 */ + USB_CONFIGUARTION_DESC_SIZE, /* bLength */ + USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL( /* wTotalLength */ + 1*USB_CONFIGUARTION_DESC_SIZE + + 1*USB_INTERFACE_DESC_SIZE + /* communication interface */ + 0x0013 + /* CDC functions */ + 1*USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */ + 1*USB_INTERFACE_DESC_SIZE + /* data interface */ + 2*USB_ENDPOINT_DESC_SIZE /* bulk endpoints */ + ), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ + 0x00, /* iConfiguration: no string to describe this configuration */ + USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ +/*USB_CONFIG_REMOTE_WAKEUP*/, + USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */ +/* Interface 0, Alternate Setting 0, Communication class interface descriptor */ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */ + WBVAL(CDC_V1_10), /* 1.10 */ /* bcdCDC */ +/*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */ + 0x01, /* bmCapabilities: device handles call management */ + 0x01, /* bDataInterface: CDC data IF ID */ +/*Abstract Control Management Functional Descriptor*/ + 0x04, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */ +/*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + CDC_UNION, /* bDescriptorSubtype: Union func desc */ + USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */ + USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */ +/*Endpoint 1 Descriptor*/ /* event notification (optional) */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN(1), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ + WBVAL(0x0010), /* wMaxPacketSize */ + 0x02, /* 2ms */ /* bInterval */ +/* Interface 1, Alternate Setting 0, Data class interface descriptor*/ + USB_INTERFACE_DESC_SIZE, /* bLength */ + USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: no alternate setting */ + 0x02, /* bNumEndpoints: two endpoints used */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */ + 0x00, /* bInterfaceSubClass: no subclass available */ + 0x00, /* bInterfaceProtocol: no protocol used */ + 0x5E, /* iInterface: */ +/* Endpoint, EP3 Bulk Out */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_OUT(3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL(64), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Endpoint, EP3 Bulk In */ + USB_ENDPOINT_DESC_SIZE, /* bLength */ + USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + USB_ENDPOINT_IN(3), /* bEndpointAddress */ + USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ + WBVAL(64), /* wMaxPacketSize */ + 0x00, /* bInterval: ignore for Bulk transfer */ +/* Terminator */ + 0 /* bLength */ +}; + + + + +/* USB String Descriptor (optional) */ +const uint8_t USB_StringDescriptor[] = { +/* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0409), /* US English */ /* wLANGID */ +/* Index 0x01: Manufacturer */ + (13*2 + 2), /* bLength (13 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'M',0, + 'I',0, + 'C',0, + 'R',0, + 'O',0, + 'B',0, + 'U',0, + 'I',0, + 'L',0, + 'D',0, + 'E',0, + 'R',0, + ' ',0, +/* Index 0x02: Product */ + (17*2 + 2), /* bLength ( 17 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'L',0, + 'P',0, + 'C',0, + '1',0, + '3',0, + '4',0, + '3',0, + ' ',0, + 'C',0, + 'O',0, + 'M',0, + ' ',0, + 'P',0, + 'O',0, + 'R',0, + 'T',0, + ' ',0, +/* Index 0x03: Serial Number */ + (12*2 + 2), /* bLength (12 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'D',0, + 'E',0, + 'M',0, + 'O',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, +/* Index 0x04: Interface 0, Alternate Setting 0 */ + ( 4*2 + 2), /* bLength (4 Char + Type + lenght) */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'V',0, + 'C',0, + 'O',0, + 'M',0, +}; diff --git a/core/usbcdc/usbdesc.h b/core/usbcdc/usbdesc.h new file mode 100644 index 0000000..b6eeddc --- /dev/null +++ b/core/usbcdc/usbdesc.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbdesc.h + * Purpose: USB Descriptors Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBDESC_H__ +#define __USBDESC_H__ + + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_StringDescriptor[]; + + +#endif /* __USBDESC_H__ */ diff --git a/core/usbcdc/usbhw.c b/core/usbcdc/usbhw.c new file mode 100644 index 0000000..fdc88f1 --- /dev/null +++ b/core/usbcdc/usbhw.c @@ -0,0 +1,606 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.c + * Purpose: USB Hardware Layer Module for Philips LPC17xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "projectconfig.h" /* LPC13xx definitions */ +#include "usb.h" +#include "usbcfg.h" +#include "usbreg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" + + +/* + * USB and IO Clock configuration only. + * The same as call PeriClkIOInit(IOCON_USB); + * The purpose is to reduce the code space for + * overall USB project and reserve code space for + * USB debugging. + * Parameters: None + * Return Value: None + */ +void USBIOClkConfig( void ) +{ + /* Enable AHB clock to the GPIO domain. */ + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_GPIO; + + /* Enable Timer32_1, IOCON, and USB blocks */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG); + + // Setup USB clock + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL + + SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; + + // Wait until the USB clock is updated + while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE)); + + // Set USB clock to 48MHz (12MHz x 4) + SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4); + while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked + SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT; + + // Set USB pin functions + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT + IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK; + IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus + IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK; + IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect + + return; +} + +/* + * Delay number of clock cycles + * Parameters: Delay length + * Return Value: None + */ + +void delay (uint32_t length ) +{ + uint32_t i; + + for ( i = 0; i < length; i++ ) + { + __asm("nop"); + } + return; +} + +/* + * Get Endpoint Physical Address + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: Endpoint Physical Address + */ + +uint32_t EPAdr (uint32_t EPNum) +{ + uint32_t val; + + val = (EPNum & 0x0F) << 1; + if (EPNum & 0x80) { + val += 1; + } + return (val); +} + + +/* + * Write Command + * Parameters: cmd: Command + * Return Value: None + */ + +void WrCmd (uint32_t cmd) +{ + USB_DEVINTCLR = CCEMTY_INT; + USB_CMDCODE = cmd; + while ((USB_DEVINTST & (CCEMTY_INT | DEV_STAT_INT)) == 0); +} + + +/* + * Write Command Data + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void WrCmdDat (uint32_t cmd, uint32_t val) +{ + WrCmd(cmd); + WrCmd(val); +} + + +/* + * Write Command to Endpoint + * Parameters: cmd: Command + * val: Data + * Return Value: None + */ + +void WrCmdEP (uint32_t EPNum, uint32_t cmd) +{ + WrCmd(CMD_SEL_EP(EPAdr(EPNum))); + WrCmd(cmd); +} + + +/* + * Read Command Data + * Parameters: cmd: Command + * Return Value: Data Value + */ + +uint32_t RdCmdDat (uint32_t cmd) +{ + USB_DEVINTCLR = CCEMTY_INT | CDFULL_INT; + USB_CMDCODE = cmd; + while ((USB_DEVINTST & (CDFULL_INT | DEV_STAT_INT)) == 0); + return (USB_CMDDATA); +} + + +/* + * USB Initialize Function + * Called by the User to initialize USB + * Return Value: None + */ + +void USB_Init (void) +{ + // Setup USB clock and pins + USBIOClkConfig(); + +#if USB_FIQ_EVENT + /* It's important that only BULK and FRAME(ISO) can be routed + to FIQ. */ + USB_DEVFIQSEL = 0x01; /* SOF Use FIQ */ + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ(USB_FIQn); +#endif + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ(USB_IRQn); + + USB_Reset(); + USB_SetAddress(0); + return; +} + + +/* + * USB Connect Function + * Called by the User to Connect/Disconnect USB + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void USB_Connect (uint32_t con) +{ + WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0)); +} + + +/* + * USB Reset Function + * Called automatically on USB Reset + * Return Value: None + */ + +void USB_Reset (void) +{ + USB_DEVINTCLR = 0x000FFFFF; + /* Enable all eight(8) EPs, note: EP won't be ready until it's + configured/enabled when device sending SetEPStatus command + to the command engine. */ + USB_DEVINTEN = DEV_STAT_INT | (0xFF<<1) | + (USB_SOF_EVENT ? FRAME_INT : 0); + return; +} + + +/* + * USB Suspend Function + * Called automatically on USB Suspend + * Return Value: None + */ + +void USB_Suspend (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Resume Function + * Called automatically on USB Resume + * Return Value: None + */ + +void USB_Resume (void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Remote Wakeup Function + * Called automatically on USB Remote Wakeup + * Return Value: None + */ + +void USB_WakeUp (void) +{ + if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) + { + WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); + } +} + + +/* + * USB Remote Wakeup Configuration Function + * Parameters: cfg: Enable/Disable + * Return Value: None + */ + +void USB_WakeUpCfg (uint32_t cfg) +{ + cfg = cfg; /* Not needed */ +} + + +/* + * USB Set Address Function + * Parameters: adr: USB Address + * Return Value: None + */ + +void USB_SetAddress (uint32_t adr) +{ + WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */ + WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */ +} + + +/* + * USB Configure Function + * Parameters: cfg: Configure/Deconfigure + * Return Value: None + */ + +void USB_Configure (uint32_t cfg) +{ + WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0)); + return; +} + + +/* + * Configure USB Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Endpoint Descriptor + * Return Value: None + */ + +void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) +{ + return; +} + + +/* + * Set Direction for USB Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void USB_DirCtrlEP (uint32_t dir) +{ + dir = dir; /* Not needed */ +} + + +/* + * Enable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_EnableEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Disable USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_DisableEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA)); +} + + +/* + * Reset USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ResetEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Set Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_SetStallEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST)); +} + + +/* + * Clear Stall for USB Endpoint + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ClrStallEP (uint32_t EPNum) +{ + WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); +} + + +/* + * Clear USB Endpoint Buffer + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USB_ClearEPBuf (uint32_t EPNum) +{ + WrCmdEP(EPNum, CMD_CLR_BUF); +} + + +/* + * Read USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData) +{ + uint32_t cnt, n; + + USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay( 5 ); + + do + { + cnt = USB_RXPLEN; + } while ((cnt & PKT_DV) == 0); + cnt &= PKT_LNGTH_MASK; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + *((uint32_t __attribute__((packed)) *)pData) = USB_RXDATA; + pData += 4; + } + + USB_CTRL = 0; + + if ((EPNum & 0x80) != 0x04) + { /* Non-Isochronous Endpoint */ + WrCmdEP(EPNum, CMD_CLR_BUF); + } + + return (cnt); +} + + +/* + * Write USB Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) +{ + uint32_t n; + + USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; + /* 3 clock cycles to fetch the packet length from RAM. */ + delay( 5 ); + USB_TXPLEN = cnt; + + for (n = 0; n < (cnt + 3) / 4; n++) + { + USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData); + pData += 4; + } + + USB_CTRL = 0; + + WrCmdEP(EPNum, CMD_VALID_BUF); + + return (cnt); +} + +/* + * Get USB Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t USB_GetFrame (void) +{ + uint32_t val; + + WrCmd(CMD_RD_FRAME); + val = RdCmdDat(DAT_RD_FRAME); + val = val | (RdCmdDat(DAT_RD_FRAME) << 8); + + return (val); +} + + +/* + * USB Interrupt Service Routine + */ + +#ifdef CFG_USBCDC +void USB_IRQHandler (void) +{ + uint32_t disr, val, n, m; + + disr = USB_DEVINTST; /* Device Interrupt Status */ + USB_DEVINTCLR = disr; + + /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ + if (disr & DEV_STAT_INT) + { + WrCmd(CMD_GET_DEV_STAT); + val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */ + if (val & DEV_RST) { /* Reset */ + USB_Reset(); +#if USB_RESET_EVENT + USB_Reset_Event(); +#endif + } + if (val & DEV_CON_CH) { /* Connect change */ +#if USB_POWER_EVENT + USB_Power_Event(val & DEV_CON); +#endif + } + if (val & DEV_SUS_CH) { /* Suspend/Resume */ + if (val & DEV_SUS) { /* Suspend */ + USB_Suspend(); +#if USB_SUSPEND_EVENT + USB_Suspend_Event(); +#endif + } else { /* Resume */ + USB_Resume(); +#if USB_RESUME_EVENT + USB_Resume_Event(); +#endif + } + } + goto isr_end; + } + +#if USB_SOF_EVENT + /* Start of Frame Interrupt */ + if (disr & FRAME_INT) + { + USB_DEVINTCLR = FRAME_INT; + USB_SOF_Event(); + // SOFIRQCount++; + } +#endif + +#if USB_ERROR_EVENT + /* NO error interrupt anymore, below code can be used + as example to get error status from command engine. */ + /* Error Interrupt */ + if (disr & ERR_INT) + { + WrCmd(CMD_RD_ERR_STAT); + val = RdCmdDat(DAT_RD_ERR_STAT); + USB_Error_Event(val); + } +#endif + + /* Endpoint's Interrupt */ + if (disr & (0xFF<<1)) { + /* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */ + for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */ + /* skip frame interrupt at bit 0 in disr */ +// if (disr & ((1 << n)<<1)) { + if ((disr>>1) & (1 << n)) { + m = n >> 1; + /* clear EP interrupt by sending cmd to the command engine. */ + WrCmd(CMD_SEL_EP_CLRI(n)); + val = RdCmdDat(DAT_SEL_EP_CLRI(n)); + if ((n & 1) == 0) { /* OUT Endpoint */ + if (n == 0) { /* Control OUT Endpoint */ + if (val & EP_SEL_STP) { /* Setup Packet */ + if (USB_P_EP[0]) { + USB_P_EP[0](USB_EVT_SETUP); + continue; + } + } + } + if (USB_P_EP[m]) { + USB_P_EP[m](USB_EVT_OUT); + } + } else { /* IN Endpoint */ + if (USB_P_EP[m]) { + USB_P_EP[m](USB_EVT_IN); + } + } + } + } + } +isr_end: + return; +} + +#endif diff --git a/core/usbcdc/usbhw.h b/core/usbcdc/usbhw.h new file mode 100644 index 0000000..f31d7d3 --- /dev/null +++ b/core/usbcdc/usbhw.h @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbhw.h + * Purpose: USB Hardware Layer Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added USB_ClearEPBuf + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ + +#ifndef __USBHW_H__ +#define __USBHW_H__ + + +/* USB Error Codes */ +#define USB_ERR_PID 0x0001 /* PID Error */ +#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */ +#define USB_ERR_DCRC 0x0004 /* Data CRC Error */ +#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */ +#define USB_ERR_EOP 0x0010 /* End of Packet Error */ +#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */ +#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */ +#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */ + +/* USB Hardware Functions */ +extern void USBIOClkConfig (void); +extern void USB_Init (void); +extern void USB_Connect (uint32_t con); +extern void USB_Reset (void); +extern void USB_Suspend (void); +extern void USB_Resume (void); +extern void USB_WakeUp (void); +extern void USB_WakeUpCfg (uint32_t cfg); +extern void USB_SetAddress (uint32_t adr); +extern void USB_Configure (uint32_t cfg); +extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD); +extern void USB_DirCtrlEP (uint32_t dir); +extern void USB_EnableEP (uint32_t EPNum); +extern void USB_DisableEP (uint32_t EPNum); +extern void USB_ResetEP (uint32_t EPNum); +extern void USB_SetStallEP (uint32_t EPNum); +extern void USB_ClrStallEP (uint32_t EPNum); +extern void USB_ClearEPBuf (uint32_t EPNum); +extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData); +extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt); +extern uint32_t USB_GetFrame(void); +extern void USB_IRQHandler (void); + + +#endif /* __USBHW_H__ */ diff --git a/core/usbcdc/usbreg.h b/core/usbcdc/usbreg.h new file mode 100644 index 0000000..d059e6a --- /dev/null +++ b/core/usbcdc/usbreg.h @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBREG.H + * Purpose: USB Hardware Layer Definitions for NXP LPC13xx + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USBREG_H +#define __USBREG_H + +/* Device Interrupt Bit Definitions */ +#define FRAME_INT (0x1<<0) +#define EP0_INT (0x1<<1) +#define EP1_INT (0x1<<2) +#define EP2_INT (0x1<<3) +#define EP3_INT (0x1<<4) +#define EP4_INT (0x1<<5) +#define EP5_INT (0x1<<6) +#define EP6_INT (0x1<<7) +#define EP7_INT (0x1<<8) +#define DEV_STAT_INT (0x1<<9) +#define CCEMTY_INT (0x1<<10) +#define CDFULL_INT (0x1<<11) +#define RxENDPKT_INT (0x1<<12) +#define TxENDPKT_INT (0x1<<13) + +/* Rx & Tx Packet Length Definitions */ +#define PKT_LNGTH_MASK 0x000003FF +#define PKT_DV 0x00000400 +#define PKT_RDY 0x00000800 + +/* USB Control Definitions */ +#define CTRL_RD_EN 0x00000001 +#define CTRL_WR_EN 0x00000002 + +/* Command Codes */ +#define CMD_SET_ADDR 0x00D00500 +#define CMD_CFG_DEV 0x00D80500 +#define CMD_SET_MODE 0x00F30500 +#define CMD_RD_INT 0x00F40500 +#define DAT_RD_INT 0x00F40200 +#define CMD_RD_FRAME 0x00F50500 +#define DAT_RD_FRAME 0x00F50200 +#define CMD_RD_CHIP_ID 0x00FD0500 +#define DAT_RD_CHIP_ID 0x00FD0200 + +#define CMD_SET_DEV_STAT 0x00FE0500 +#define CMD_GET_DEV_STAT 0x00FE0500 +#define DAT_GET_DEV_STAT 0x00FE0200 +#define CMD_GET_ERR_CODE 0x00FF0500 +#define DAT_GET_ERR_CODE 0x00FF0200 + +#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) +#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) +#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) +#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) +#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) +#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) +#define CMD_CLR_BUF 0x00F20500 +#define CMD_VALID_BUF 0x00FA0500 + +/* Device Address Register Definitions */ +#define DEV_ADDR_MASK 0x7F +#define DEV_EN 0x80 + +/* Device Configure Register Definitions */ +#define CONF_DVICE 0x01 + +/* Device Mode Register Definitions */ +#define AP_CLK 0x01 +#define INAK_CI 0x02 +#define INAK_CO 0x04 +#define INAK_AI 0x08 +#define INAK_AO 0x10 + +/* Device Status Register Definitions */ +#define DEV_CON 0x01 +#define DEV_CON_CH 0x02 +#define DEV_SUS 0x04 +#define DEV_SUS_CH 0x08 +#define DEV_RST 0x10 + +/* Error Code Register Definitions */ +#define ERR_EC_MASK 0x0F +#define ERR_EA 0x10 + +/* Error Status Register Definitions */ +#define ERR_NOERROR 0x00 +#define ERR_PID_ENCODE 0x01 +#define ERR_UNKNOWN_PID 0x02 +#define ERR_UNEXPECT_PKT 0x03 +#define ERR_TCRC 0x04 +#define ERR_DCRC 0x05 +#define ERR_TIMEOUT 0x06 +#define ERR_BABBIE 0x07 +#define ERR_EOF_PKT 0x08 +#define ERR_TX_RX_NAK 0x09 +#define ERR_SENT_STALL 0x0A +#define ERR_BUF_OVERRUN 0x0B +#define ERR_SENT_EPT_PKT 0x0C +#define ERR_BIT_STUFF 0x0D +#define ERR_SYNC 0x0E +#define ERR_TOGGLE_BIT 0x0F + +/* Endpoint Select Register Definitions */ +#define EP_SEL_F 0x01 +#define EP_SEL_ST 0x02 +#define EP_SEL_STP 0x04 +#define EP_SEL_PO 0x08 +#define EP_SEL_EPN 0x10 +#define EP_SEL_B_1_FULL 0x20 +#define EP_SEL_B_2_FULL 0x40 + +/* Endpoint Status Register Definitions */ +#define EP_STAT_ST 0x01 +#define EP_STAT_DA 0x20 +#define EP_STAT_RF_MO 0x40 +#define EP_STAT_CND_ST 0x80 + +/* Clear Buffer Register Definitions */ +#define CLR_BUF_PO 0x01 + +#endif /* __USBREG_H */ diff --git a/core/usbcdc/usbuser.c b/core/usbcdc/usbuser.c new file mode 100644 index 0000000..54f7b9e --- /dev/null +++ b/core/usbcdc/usbuser.c @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbuser.c + * Purpose: USB Custom User Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ +#include "projectconfig.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbuser.h" +#include "cdcuser.h" + + +/* + * USB Power Event Callback + * Called automatically on USB Power Event + * Parameter: power: On(TRUE)/Off(FALSE) + */ + +#if USB_POWER_EVENT +void USB_Power_Event (uint32_t power) { +} +#endif + + +/* + * USB Reset Event Callback + * Called automatically on USB Reset Event + */ + +#if USB_RESET_EVENT +void USB_Reset_Event (void) { + USB_ResetCore(); +} +#endif + + +/* + * USB Suspend Event Callback + * Called automatically on USB Suspend Event + */ + +#if USB_SUSPEND_EVENT +void USB_Suspend_Event (void) { +} +#endif + + +/* + * USB Resume Event Callback + * Called automatically on USB Resume Event + */ + +#if USB_RESUME_EVENT +void USB_Resume_Event (void) { +} +#endif + + +/* + * USB Remote Wakeup Event Callback + * Called automatically on USB Remote Wakeup Event + */ + +#if USB_WAKEUP_EVENT +void USB_WakeUp_Event (void) { +} +#endif + + +/* + * USB Start of Frame Event Callback + * Called automatically on USB Start of Frame Event + */ + +#if USB_SOF_EVENT +void USB_SOF_Event (void) { +} +#endif + + +/* + * USB Error Event Callback + * Called automatically on USB Error Event + * Parameter: error: Error Code + */ + +#if USB_ERROR_EVENT +void USB_Error_Event (uint32_t error) { +} +#endif + + +/* + * USB Set Configuration Event Callback + * Called automatically on USB Set Configuration Request + */ + +#if USB_CONFIGURE_EVENT +void USB_Configure_Event (void) { + + if (USB_Configuration) { /* Check if USB is configured */ + /* add your code here */ + } +} +#endif + + +/* + * USB Set Interface Event Callback + * Called automatically on USB Set Interface Request + */ + +#if USB_INTERFACE_EVENT +void USB_Interface_Event (void) { +} +#endif + + +/* + * USB Set/Clear Feature Event Callback + * Called automatically on USB Set/Clear Feature Request + */ + +#if USB_FEATURE_EVENT +void USB_Feature_Event (void) { +} +#endif + + +#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL) + +/* USB Endpoint Events Callback Pointers */ +void (* const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = { + P_EP(0), + P_EP(1), + P_EP(2), + P_EP(3), + P_EP(4), +}; + + +/* + * USB Endpoint 1 Event Callback + * Called automatically on USB Endpoint 1 Event + * Parameter: event + */ + +void USB_EndPoint1 (uint32_t event) { + uint16_t temp; + static uint16_t serialState; + + switch (event) { + case USB_EVT_IN: + temp = CDC_GetSerialState(); + if (serialState != temp) { + serialState = temp; + CDC_NotificationIn(); /* send SERIAL_STATE notification */ + } + break; + } +} + + +/* + * USB Endpoint 2 Event Callback + * Called automatically on USB Endpoint 2 Event + * Parameter: event + */ + +void USB_EndPoint2 (uint32_t event) +{ + event = event; +} + + +/* + * USB Endpoint 3 Event Callback + * Called automatically on USB Endpoint 3 Event + * Parameter: event + */ + +void USB_EndPoint3 (uint32_t event) { + switch (event) { + case USB_EVT_OUT: + CDC_BulkOut (); /* data received from Host */ + break; + case USB_EVT_IN: + CDC_BulkIn (); /* data expected from Host */ + break; + } +} + + diff --git a/core/usbcdc/usbuser.h b/core/usbcdc/usbuser.h new file mode 100644 index 0000000..e4109ec --- /dev/null +++ b/core/usbcdc/usbuser.h @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: USBUSER.H + * Purpose: USB Custom User Definitions + * Version: V1.10 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2005-2009 Keil Software. + *---------------------------------------------------------------------------*/ + +#ifndef __USBUSER_H__ +#define __USBUSER_H__ + + +/* USB Device Events Callback Functions */ +extern void USB_Power_Event (uint32_t power); +extern void USB_Reset_Event (void); +extern void USB_Suspend_Event (void); +extern void USB_Resume_Event (void); +extern void USB_WakeUp_Event (void); +extern void USB_SOF_Event (void); +extern void USB_Error_Event (uint32_t error); + +/* USB Endpoint Callback Events */ +#define USB_EVT_SETUP 1 /* Setup Packet */ +#define USB_EVT_OUT 2 /* OUT Packet */ +#define USB_EVT_IN 3 /* IN Packet */ +#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */ +#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */ +#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */ +#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */ + +/* USB Endpoint Events Callback Pointers */ +extern void (* const USB_P_EP[USB_LOGIC_EP_NUM])(uint32_t event); + +/* USB Endpoint Events Callback Functions */ +extern void USB_EndPoint0 (uint32_t event); +extern void USB_EndPoint1 (uint32_t event); +extern void USB_EndPoint2 (uint32_t event); +extern void USB_EndPoint3 (uint32_t event); +extern void USB_EndPoint4 (uint32_t event); + +/* USB Core Events Callback Functions */ +extern void USB_Configure_Event (void); +extern void USB_Interface_Event (void); +extern void USB_Feature_Event (void); + + +#endif /* __USBUSER_H__ */ diff --git a/core/usbhid-rom/usb.h b/core/usbhid-rom/usb.h new file mode 100644 index 0000000..2e55b8c --- /dev/null +++ b/core/usbhid-rom/usb.h @@ -0,0 +1,240 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usb.h + * Purpose: USB Definitions + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC microcontroller devices only. Nothing else + * gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef __USB_H__ +#define __USB_H__ + +#include "sysdefs.h" + +typedef union +{ + uint16_t W; + struct + { + uint8_t L; + uint8_t H; + } __attribute__ ((packed)) WB; +} __attribute__ ((packed)) WORD_BYTE; + + +/* bmRequestType.Dir */ +#define REQUEST_HOST_TO_DEVICE 0 +#define REQUEST_DEVICE_TO_HOST 1 + +/* bmRequestType.Type */ +#define REQUEST_STANDARD 0 +#define REQUEST_CLASS 1 +#define REQUEST_VENDOR 2 +#define REQUEST_RESERVED 3 + +/* bmRequestType.Recipient */ +#define REQUEST_TO_DEVICE 0 +#define REQUEST_TO_INTERFACE 1 +#define REQUEST_TO_ENDPOINT 2 +#define REQUEST_TO_OTHER 3 + +/* bmRequestType Definition */ +typedef union _REQUEST_TYPE +{ + struct _BM + { + uint8_t Recipient : 5; + uint8_t Type : 2; + uint8_t Dir : 1; + } __attribute__ ((packed)) BM; + uint8_t B; +} __attribute__ ((packed)) REQUEST_TYPE; + +/* USB Standard Request Codes */ +#define USB_REQUEST_GET_STATUS 0 +#define USB_REQUEST_CLEAR_FEATURE 1 +#define USB_REQUEST_SET_FEATURE 3 +#define USB_REQUEST_SET_ADDRESS 5 +#define USB_REQUEST_GET_DESCRIPTOR 6 +#define USB_REQUEST_SET_DESCRIPTOR 7 +#define USB_REQUEST_GET_CONFIGURATION 8 +#define USB_REQUEST_SET_CONFIGURATION 9 +#define USB_REQUEST_GET_INTERFACE 10 +#define USB_REQUEST_SET_INTERFACE 11 +#define USB_REQUEST_SYNC_FRAME 12 + +/* USB GET_STATUS Bit Values */ +#define USB_GETSTATUS_SELF_POWERED 0x01 +#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 +#define USB_GETSTATUS_ENDPOINT_STALL 0x01 + +/* USB Standard Feature selectors */ +#define USB_FEATURE_ENDPOINT_STALL 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 + +/* USB Default Control Pipe Setup Packet */ +typedef struct _USB_SETUP_PACKET +{ + REQUEST_TYPE bmRequestType; + uint8_t bRequest; + WORD_BYTE wValue; + WORD_BYTE wIndex; + uint16_t wLength; +} __attribute__ ((packed)) USB_SETUP_PACKET; + + +/* USB Descriptor Types */ +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 +#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 +#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 +#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 +#define USB_OTG_DESCRIPTOR_TYPE 9 +#define USB_DEBUG_DESCRIPTOR_TYPE 10 +#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11 + +/* USB Device Classes */ +#define USB_DEVICE_CLASS_RESERVED 0x00 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_MONITOR 0x04 +#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 +#define USB_DEVICE_CLASS_POWER 0x06 +#define USB_DEVICE_CLASS_PRINTER 0x07 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_HUB 0x09 +#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +/* bmAttributes in Configuration Descriptor */ +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +/* bMaxPower in Configuration Descriptor */ +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +/* bEndpointAddress in Endpoint Descriptor */ +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +/* bmAttributes in Endpoint Descriptor */ +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 +#define USB_ENDPOINT_SYNC_MASK 0x0C +#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 +#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 +#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 +#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C +#define USB_ENDPOINT_USAGE_MASK 0x30 +#define USB_ENDPOINT_USAGE_DATA 0x00 +#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 +#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 +#define USB_ENDPOINT_USAGE_RESERVED 0x30 + +/* USB Standard Device Descriptor */ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR; + +/* USB 2.0 Device Qualifier Descriptor */ +typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR; + +/* USB Standard Configuration Descriptor */ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR; + +/* USB Standard Interface Descriptor */ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR; + +/* USB Standard Endpoint Descriptor */ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR; + +/* USB String Descriptor */ +typedef struct _USB_STRING_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString/*[]*/; +} __attribute__ ((packed)) USB_STRING_DESCRIPTOR; + +/* USB Common Descriptor */ +typedef struct _USB_COMMON_DESCRIPTOR +{ + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR; + +#endif diff --git a/core/usbhid-rom/usbconfig.c b/core/usbhid-rom/usbconfig.c new file mode 100644 index 0000000..6fa0a7f --- /dev/null +++ b/core/usbhid-rom/usbconfig.c @@ -0,0 +1,115 @@ +/**************************************************************************/ +/*! + @file usbconfig.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "usb.h" +#include "usbconfig.h" + +#ifndef WBVAL +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) +#endif + +/* USB String Descriptor (optional) */ +const uint8_t USB_HIDStringDescriptor[] = +{ + /* Index 0x00: LANGID Codes */ + 0x04, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + WBVAL(0x0409), /* US English */ /* wLANGID */ + /* Index 0x04: Manufacturer */ + 0x1C, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'm',0, + 'i',0, + 'c',0, + 'r',0, + 'o',0, + 'B',0, + 'u',0, + 'i',0, + 'l',0, + 'd',0, + 'e',0, + 'r',0, + ' ',0, + /* Index 0x20: Product */ + 0x28, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'L',0, + 'P',0, + 'C',0, + '1',0, + '3',0, + '4',0, + '3',0, + ' ',0, + 'R',0, + 'e',0, + 'f',0, + '.',0, + ' ',0, + 'B',0, + 'o',0, + 'a',0, + 'r',0, + 'd',0, + ' ',0, + /* Index 0x48: Serial Number */ + 0x1A, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + '0',0, + /* Index 0x62: Interface 0, Alternate Setting 0 */ + 0x0E, /* bLength */ + USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ + 'H',0, + 'I',0, + 'D',0, + ' ',0, + ' ',0, + ' ',0, +}; diff --git a/core/usbhid-rom/usbconfig.h b/core/usbhid-rom/usbconfig.h new file mode 100644 index 0000000..9cc9110 --- /dev/null +++ b/core/usbhid-rom/usbconfig.h @@ -0,0 +1,66 @@ +/**************************************************************************/ +/*! + @file usbconfig.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _USBCONFIG_H_ +#define _USBCONFIG_H_ + +#include "projectconfig.h" + +#define USB_VENDOR_ID CFG_USB_VID // Vendor ID +#define USB_PROD_ID CFG_USB_PID // Product ID +#define USB_DEVICE 0x0100 // Device ID + +#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) +#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) +#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) +#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) + +#define HID_DESC_OFFSET 0x0012 +#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR)) +#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor)) + +extern const uint8_t USB_DeviceDescriptor[]; +extern const uint8_t USB_ConfigDescriptor[]; +extern const uint8_t USB_HIDStringDescriptor[]; + +extern const uint8_t HID_ReportDescriptor[]; +extern const uint16_t HID_ReportDescSize; + +#endif \ No newline at end of file diff --git a/core/usbhid-rom/usbhid.c b/core/usbhid-rom/usbhid.c new file mode 100644 index 0000000..ce53742 --- /dev/null +++ b/core/usbhid-rom/usbhid.c @@ -0,0 +1,222 @@ +/**************************************************************************/ +/*! + @file usbhid.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "core/usbhid-rom/usb.h" +#include "core/usbhid-rom/usbconfig.h" +#include "core/rom_drivers.h" +#include "core/gpio/gpio.h" +#include "core/adc/adc.h" +#include "core/systick/systick.h" + +#include "usbhid.h" + +USB_DEV_INFO DeviceInfo; +HID_DEVICE_INFO HidDevInfo; +ROM ** rom = (ROM **)0x1fff1ff8; + +typedef struct usbhid_out_s +{ + uint16_t gpio1Dir; + uint16_t gpio1Data; + uint16_t gpio2Dir; + uint16_t gpio2Data; + uint16_t gpio3Dir; + uint16_t gpio3Data; + uint16_t adc0; + uint16_t adc1; + uint16_t adc2; + uint16_t adc3; + uint32_t systicks; + uint32_t rollovers; +} usbhid_out_t; + +/**************************************************************************/ +/*! + @brief Gets the HID In Report (the report going from the LPC1343 to + the USB host) +*/ +/**************************************************************************/ +void usbHIDGetInReport (uint8_t src[], uint32_t length) +{ + usbhid_out_t out; + + out.gpio1Dir = GPIO_GPIO1DIR; + out.gpio1Data = GPIO_GPIO1DATA; + out.gpio2Dir = GPIO_GPIO2DIR; + out.gpio2Data = GPIO_GPIO2DATA; + out.gpio3Dir = GPIO_GPIO3DIR; + out.gpio3Data = GPIO_GPIO3DATA; + out.adc0 = adcRead(0); + out.adc1 = adcRead(1); + out.adc2 = adcRead(2); + out.adc3 = adcRead(3); + out.systicks = systickGetTicks(); + out.rollovers = systickGetRollovers(); + + size_t i = 0; + memcpy(&src[i], &out.gpio1Dir, sizeof out.gpio1Dir); + i += sizeof out.gpio1Dir; + memcpy(&src[i], &out.gpio1Data, sizeof out.gpio1Data); + i += sizeof out.gpio1Data; + memcpy(&src[i], &out.gpio2Dir, sizeof out.gpio2Dir); + i += sizeof out.gpio2Dir; + memcpy(&src[i], &out.gpio2Data, sizeof out.gpio2Data); + i += sizeof out.gpio2Data; + memcpy(&src[i], &out.gpio3Dir, sizeof out.gpio3Dir); + i += sizeof out.gpio3Dir; + memcpy(&src[i], &out.gpio3Data, sizeof out.gpio3Data); + i += sizeof out.gpio3Data; + memcpy(&src[i], &out.adc0, sizeof out.adc0); + i += sizeof out.adc0; + memcpy(&src[i], &out.adc1, sizeof out.adc1); + i += sizeof out.adc1; + memcpy(&src[i], &out.adc2, sizeof out.adc2); + i += sizeof out.adc2; + memcpy(&src[i], &out.adc3, sizeof out.adc3); + i += sizeof out.adc3; + memcpy(&src[i], &out.systicks, sizeof out.systicks); + i += sizeof out.systicks; + memcpy(&src[i], &out.rollovers, sizeof out.rollovers); + i += sizeof out.rollovers; +} + +/**************************************************************************/ +/*! + @brief Sets the HID Out Report (the report coming in from the USB + host to the LPC1343). +*/ +/**************************************************************************/ +void usbHIDSetOutReport (uint8_t dst[], uint32_t length) +{ + uint8_t PCOutReportData = dst[0]; + // Check bit 0 in the incoming report to determine is LED should + // be enabled or disabled (1 = enabled, 0 = disabled) + if (PCOutReportData & (1<<0)) + { + // Enable LED (set low) + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 0); + } + else + { + // Disable LED (set high) + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 1); + } +} + +/**************************************************************************/ +/*! + @brief Initialises the USB port + + The ROM-based USB HID code is capable of configuring the PLL and pins + for USB, but there seems to be a bug in the code that sets the system + clock to 48MHz (normally the USB and System clocks can be configured + seperately). As such, this code does not use the "init_clk_pins()" + function in the rom, and the USB clock and pins are manually + configured. +*/ +/**************************************************************************/ +void usbHIDInit (void) +{ + // Setup USB clock + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY + SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL + + SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register + SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; + + // Wait until the USB clock is updated + while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE)); + + // Set USB clock to 48MHz (12MHz x 4) + SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4); + while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked + SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT; + + // Set USB pin functions + IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK; + IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT + IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK; + IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus + IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK; + IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect + + // Disable internal resistor on VBUS (0.3) + gpioSetPullup(&IOCON_PIO0_3, gpioPullupMode_Inactive); + + // HID Device Info + volatile int n; + HidDevInfo.idVendor = USB_VENDOR_ID; + HidDevInfo.idProduct = USB_PROD_ID; + HidDevInfo.bcdDevice = USB_DEVICE; + HidDevInfo.StrDescPtr = (uint32_t)&USB_HIDStringDescriptor[0]; + HidDevInfo.InReportCount = sizeof(usbhid_out_t); + HidDevInfo.OutReportCount = 1; + HidDevInfo.SampleInterval = 0x20; + HidDevInfo.InReport = usbHIDGetInReport; + HidDevInfo.OutReport = usbHIDSetOutReport; + + DeviceInfo.DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE; + DeviceInfo.DevDetailPtr = (uint32_t)&HidDevInfo; + + /* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG); + + /* Use pll and pin init function in rom */ + /* Warning: This will also set the system clock to 48MHz! */ + // (*rom)->pUSBD->init_clk_pins(); + + /* insert a delay between clk init and usb init */ + for (n = 0; n < 75; n++) {__asm("nop");} + + (*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */ + (*rom)->pUSBD->connect(true); /* USB Connect */ +} + +/**************************************************************************/ +/*! + @brief Passes the USB interrupt to the internal ROM-based handler +*/ +/**************************************************************************/ +#ifdef CFG_USBHID +void USB_IRQHandler() +{ + (*rom)->pUSBD->isr(); +} +#endif + diff --git a/core/usbhid-rom/usbhid.h b/core/usbhid-rom/usbhid.h new file mode 100644 index 0000000..31247dc --- /dev/null +++ b/core/usbhid-rom/usbhid.h @@ -0,0 +1,46 @@ +/**************************************************************************/ +/*! + @file usbhid.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _USBCONFIG_H_ +#define _USBCONFIG_H_ + +#include "projectconfig.h" + +void usbHIDGetInReport (uint8_t src[], uint32_t length); +void usbHIDSetOutReport (uint8_t dst[], uint32_t length); +void usbHIDInit (void); + +#endif diff --git a/core/wdt/wdt.c b/core/wdt/wdt.c new file mode 100644 index 0000000..3cd823b --- /dev/null +++ b/core/wdt/wdt.c @@ -0,0 +1,152 @@ +/**************************************************************************/ +/*! + @file wdt.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Sets up the watchdog timer (WDT). The WDT allows you to monitor + whether the device is still executing properly. If the watchdog + isn't 'fed' within a pre-determined delay, it will raise an interrupt + allowing you to decide if you want to reset the device, etc. + + @code + #include "core/cpu/cpu.h" + #include "core/wdt/wdt.h" + ... + cpuInit(); + + // Initialise wdt with no reset on timeout + wdtInit(false); + + // Pat the watchdog (to start the timer) + wdtFeed(); + + while (1) + { + // Keep the watchdog happy by regularly feeding it + wdtFeed(); + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "wdt.h" + +#define WDT_FEED_VALUE (0x003FFFFF) + +volatile uint32_t wdt_counter; + +/**************************************************************************/ +/*! + IRQ Handler when the watchdog times out. Any actions that you wish + to take when a timeout occurs should be called from here. +*/ +/**************************************************************************/ +void WDT_IRQHandler(void) +{ + /* Clear the time-out interrupt flag */ + WDT_WDMOD &= ~WDT_WDMOD_WDTOF; + wdt_counter++; +} + +/**************************************************************************/ +/*! + Setup the clock for the watchdog timer. The default setting is 250kHz. +*/ +/**************************************************************************/ +static void wdtClockSetup (void) +{ + /* Watchdog Configuration */ + /* Freq. = 0.5MHz, div = 2: WDT_OSC = 250kHz */ + SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ | + SCB_WDTOSCCTRL_DIVSEL_DIV2; + + /* Set clock source (use WDT oscillator) */ + SCB_WDTCLKSEL = SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_DISABLE; + SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE; + + /* Wait until updated */ + while (!(SCB_WDTCLKUEN & SCB_WDTCLKUEN_UPDATE)); + + /* Set divider */ + SCB_WDTCLKDIV = SCB_WDTCLKDIV_DIV1; + + /* Enable WDT clock */ + SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC); +} + +/**************************************************************************/ +/*! + Initialises the watchdog timer and sets up the interrupt. +*/ +/**************************************************************************/ +void wdtInit (bool reset) +{ + /* Setup the WDT clock */ + wdtClockSetup(); + + /* Enable AHB clock to the WDT domain. */ + SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_WDT; + + wdt_counter = 0; + + /* Enable the WDT interrupt */ + NVIC_EnableIRQ(WDT_IRQn); + + /* Set timeout value (must be at least 0x000000FF) */ + WDT_WDTC = WDT_FEED_VALUE; + + /* Enable the watchdog timer (without system reset) */ + WDT_WDMOD = WDT_WDMOD_WDEN_ENABLED | + reset ? WDT_WDMOD_WDRESET_ENABLED : WDT_WDMOD_WDRESET_DISABLED ; +} + +/**************************************************************************/ +/*! + Feeds the watchdog to keep it from timing out. Interrupts will be + disabled while feeding the watchdog. +*/ +/**************************************************************************/ +void wdtFeed (void) +{ + /* Pet the watchdog */ + __disable_irq(); + WDT_WDFEED = WDT_WDFEED_FEED1; + WDT_WDFEED = WDT_WDFEED_FEED2; + __enable_irq(); +} + diff --git a/core/wdt/wdt.h b/core/wdt/wdt.h new file mode 100644 index 0000000..55f4b48 --- /dev/null +++ b/core/wdt/wdt.h @@ -0,0 +1,47 @@ +/**************************************************************************/ +/*! + @file wdt.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _WDT_H_ +#define _WDT_H_ + +#include "projectconfig.h" + +void wdtInit (bool reset); +void wdtFeed (void); + +#endif \ No newline at end of file diff --git a/drivers/chibi/chb.c b/drivers/chibi/chb.c new file mode 100644 index 0000000..e5a56dd --- /dev/null +++ b/drivers/chibi/chb.c @@ -0,0 +1,229 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#include +#include + +#include "chb.h" +#include "chb_drvr.h" +#include "chb_buf.h" + +static chb_pcb_t pcb; +// these are for the duplicate checking and rejection +static U8 prev_seq = 0xFF; +static U16 prev_src_addr = 0xFFFE; +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_init() +{ + memset(&pcb, 0, sizeof(chb_pcb_t)); + pcb.src_addr = chb_get_short_addr(); + chb_drvr_init(); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +chb_pcb_t *chb_get_pcb() +{ + return &pcb; +} + +/**************************************************************************/ +/*! + Requires the dest addr, location to store data, and len of payload. + Returns the length of the hdr. +*/ +/**************************************************************************/ +static U8 chb_gen_hdr(U8 *hdr, U16 addr, U8 len) +{ + U8 *hdr_ptr = hdr; + + // calc frame size and put in 0 position of array + // frame size = hdr sz + payload len + fcs len + *hdr_ptr++ = CHB_HDR_SZ + len + CHB_FCS_LEN; + + // use default fcf byte 0 val but test for ack request. we won't request + // ack if broadcast. all other cases we will. + *hdr_ptr++ = CHB_FCF_BYTE_0 | ((addr != 0xFFFF) << CHB_ACK_REQ_POS); + *hdr_ptr++ = CHB_FCF_BYTE_1; + + *hdr_ptr++ = pcb.seq++; + + // fill out dest pan ID, dest addr, src addr + *(U16 *)hdr_ptr = CFG_CHIBI_PANID; + hdr_ptr += sizeof(U16); + *(U16 *)hdr_ptr = addr; + hdr_ptr += sizeof(U16); + *(U16 *)hdr_ptr = pcb.src_addr; + hdr_ptr += sizeof(U16); + + // return the len of the header + return hdr_ptr - hdr; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U8 chb_write(U16 addr, U8 *data, U8 len) +{ + U8 status, frm_len, hdr_len, hdr[CHB_HDR_SZ + 1]; + + while (len > 0) + { + // calculate which frame len to use. if greater than max payload, split + // up operation. + frm_len = (len > CHB_MAX_PAYLOAD) ? CHB_MAX_PAYLOAD : len; + + // gen frame header + hdr_len = chb_gen_hdr(hdr, addr, frm_len); + + // send data to chip + status = chb_tx(hdr, data, frm_len); + + if (status != CHB_SUCCESS) + { + switch (status) + { + case RADIO_SUCCESS: + // fall through + case CHB_SUCCESS_DATA_PENDING: + pcb.txd_success++; + break; + + case CHB_NO_ACK: + pcb.txd_noack++; + break; + + case CHB_CHANNEL_ACCESS_FAILURE: + pcb.txd_channel_fail++; + break; + + default: + break; + } + return status; + } + + // adjust len and restart + len = len - frm_len; + } + return CHB_SUCCESS; +} + +/**************************************************************************/ +/*! + Read data from the buffer. Need to pass in a buffer of at leasts max frame + size and two 16-bit containers for the src and dest addresses. + + The read function will automatically populate the addresses and the data with + the frm payload. It will then return the len of the payload. +*/ +/**************************************************************************/ +U8 chb_read(chb_rx_data_t *rx) +{ + U8 i, len, seq, *data_ptr; + + data_ptr = rx->data; + + // first byte is always len. check it to make sure + // we have a valid len byte. + if ((len = chb_buf_read()) > CHB_MAX_FRAME_LENGTH) + { + return 0; + } + *data_ptr++ = len; + + // load the rest of the data into buffer + for (i=0; idata + 3; // location of sequence number + seq = *data_ptr; + + // parse the buffer and extract the dest and src addresses + data_ptr = rx->data + 6; // location of dest addr + rx->dest_addr = *(U16 *)data_ptr; + data_ptr += sizeof(U16); + rx->src_addr = *(U16 *)data_ptr; + data_ptr += sizeof(U16); + + // if the data in the rx buf is 0, then clear the rx_flag. otherwise, keep it raised + if (!chb_buf_get_len()) + { + pcb.data_rcv = false; + } + +#if (CFG_CHIBI_PROMISCUOUS == 1) + // if we're in promiscuous mode, we don't want to do any duplicate rejection and we don't want to move the payload + // to the front of the buffer. We want to capture the full frame so just keep the frame intact and return the length. + return len; +#else + // duplicate frame check (dupe check). we want to remove frames that have been already been received since they + // are just retries. + // note: this dupe check only removes duplicate frames from the previous transfer. if another frame from a different + // node comes in between the dupes, then the dupe will show up as a received frame. + if ((seq == prev_seq) && (rx->src_addr == prev_src_addr)) + { + // this is a duplicate frame from a retry. the remote node thinks we didn't receive + // it properly. discard. + return 0; + } + else + { + prev_seq = seq; + prev_src_addr = rx->src_addr; + } + + // move the payload down to the beginning of the data buffer + memmove(rx->data, data_ptr, len - CHB_HDR_SZ); + // finally, return the len of the payload + return len - CHB_HDR_SZ - CHB_FCS_LEN; +#endif +} + diff --git a/drivers/chibi/chb.h b/drivers/chibi/chb.h new file mode 100644 index 0000000..6fb7827 --- /dev/null +++ b/drivers/chibi/chb.h @@ -0,0 +1,100 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#ifndef CHIBI_H +#define CHIBI_H + +#include "types.h" + +#define CHB_HDR_SZ 9 // FCF + seq + pan_id + dest_addr + src_addr (2 + 1 + 2 + 2 + 2) +#define CHB_FCS_LEN 2 +#define CHB_MAX_PAYLOAD 100 + + +// frame_type = data +// security enabled = false +// frame pending = false +// ack request = false +// pan ID compression = true +#define CHB_FCF_BYTE_0 0x41 + +// dest addr = 16-bit +// frame version = 802.15.4 (not 2003) +// src addr = 16-bit +#define CHB_FCF_BYTE_1 0x98 + +#define CHB_ACK_REQ_POS 5 + +enum +{ + CHB_SUCCESS = 0, + CHB_SUCCESS_DATA_PENDING = 1, + CHB_CHANNEL_ACCESS_FAILURE = 3, + CHB_NO_ACK = 5, + CHB_INVALID = 7 +}; + +// Chibi Protocol control block +typedef struct +{ + U16 src_addr; + U8 seq; + volatile bool data_rcv; + volatile bool tx_end; + + // stats + U16 rcvd_xfers; + U16 txd_success; + U16 txd_noack; + U16 txd_channel_fail; + U16 overflow; + U16 underrun; + U8 battlow; + U8 ed; + U8 crc; +} chb_pcb_t; + +typedef struct +{ + U8 len; + U16 src_addr; + U16 dest_addr; + U8 data[CHB_MAX_PAYLOAD]; +} chb_rx_data_t; + +void chb_init(); +chb_pcb_t *chb_get_pcb(); +U8 chb_write(U16 addr, U8 *data, U8 len); +U8 chb_read(chb_rx_data_t *rx); + +#endif diff --git a/drivers/chibi/chb_buf.c b/drivers/chibi/chb_buf.c new file mode 100644 index 0000000..a08c856 --- /dev/null +++ b/drivers/chibi/chb_buf.c @@ -0,0 +1,89 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#include +#include "chb_buf.h" +#include "projectconfig.h" + +static U8 chb_buf[CFG_CHIBI_BUFFERSIZE]; +static volatile U32 rd_ptr, wr_ptr; +static volatile U32 len; + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_buf_init() +{ + rd_ptr = 0; + wr_ptr = 0; + len = 0; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_buf_write(U8 data) +{ + chb_buf[wr_ptr] = data; + wr_ptr = (wr_ptr + 1) % CFG_CHIBI_BUFFERSIZE; + len++; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U8 chb_buf_read() +{ + U8 data; + + data = chb_buf[rd_ptr]; + rd_ptr = (rd_ptr + 1) % CFG_CHIBI_BUFFERSIZE; + len--; + return data; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U32 chb_buf_get_len() +{ + return len; +} diff --git a/drivers/chibi/chb_buf.h b/drivers/chibi/chb_buf.h new file mode 100644 index 0000000..ec75812 --- /dev/null +++ b/drivers/chibi/chb_buf.h @@ -0,0 +1,44 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#ifndef CHB_BUF_H +#define CHB_BUF_H + +#include "types.h" + +void chb_buf_init(); +void chb_buf_write(U8 data); +U8 chb_buf_read(); +U32 chb_buf_get_len(); + +#endif diff --git a/drivers/chibi/chb_drvr.c b/drivers/chibi/chb_drvr.c new file mode 100644 index 0000000..c56531a --- /dev/null +++ b/drivers/chibi/chb_drvr.c @@ -0,0 +1,917 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#include +#include "chb.h" +#include "chb_drvr.h" +#include "chb_buf.h" +#include "chb_spi.h" +#include "chb_eeprom.h" + +#include "core/systick/systick.h" +#include "core/timer16/timer16.h" + +// store string messages in flash rather than RAM +const char chb_err_overflow[] = "BUFFER FULL. TOSSING INCOMING DATA\r\n"; +const char chb_err_init[] = "RADIO NOT INITIALIZED PROPERLY\r\n"; +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +static U8 chb_get_state() +{ + return chb_reg_read(TRX_STATUS) & 0x1f; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +static U8 chb_get_status() +{ + return chb_reg_read(TRX_STATE) >> CHB_TRAC_STATUS_POS; +} + +/**************************************************************************/ +/*! + Cause a blocking delay for x microseconds +*/ +/**************************************************************************/ +static void chb_delay_us(U16 usec) +{ + // Determine maximum delay using a 16 bit timer + // ToDo: Move this to a macro or fixed value! + uint32_t maxus = 0xFFFF / (CFG_CPU_CCLK / 1000000); + + // Check if delay can be done in one operation + if (usec <= maxus) + { + timer16DelayUS(0, usec); + return; + } + + // Split delay into several steps (to stay within limit of 16-bit timer) + do + { + if (usec >= maxus) + { + timer16DelayUS(0, maxus); + usec -= maxus; + } + else + { + timer16DelayUS(0, usec); + usec = 0; + } + } while (usec > 0); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_reset() +{ + CHB_RST_DISABLE(); + CHB_SLPTR_DISABLE(); + + // wait a bit while transceiver wakes up + chb_delay_us(TIME_P_ON_TO_CLKM_AVAIL); + + // reset the device + CHB_RST_ENABLE(); + chb_delay_us(TIME_RST_PULSE_WIDTH); + CHB_RST_DISABLE(); + + // check that we have the part number that we're expecting + while (1) + { + // if you're stuck in this loop, that means that you're not reading + // the version and part number register correctly. possible that version number + // changes. if so, update version num in header file + if ((chb_reg_read(VERSION_NUM) == CHB_AT86RF212_VER_NUM) && (chb_reg_read(PART_NUM) == CHB_AT86RF212_PART_NUM)) + { + break; + } + } +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U8 chb_reg_read(U8 addr) +{ + U8 val = 0; + + /* Add the register read command to the register address. */ + addr |= 0x80; + + CHB_ENTER_CRIT(); + CHB_SPI_ENABLE(); + + /*Send Register address and read register content.*/ + val = chb_xfer_byte(addr); + val = chb_xfer_byte(val); + + CHB_SPI_DISABLE(); + CHB_LEAVE_CRIT(); + + return val; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U16 chb_reg_read16(U8 addr) +{ + U8 i; + U16 val = 0; + + for (i=0; i<2; i++) + { + addr |= chb_reg_read(addr + i) << (8 * i); + } + return val; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_reg_write(U8 addr, U8 val) +{ + U8 dummy; + + /* Add the Register Write command to the address. */ + addr |= 0xC0; + + CHB_ENTER_CRIT(); + CHB_SPI_ENABLE(); + + /*Send Register address and write register content.*/ + dummy = chb_xfer_byte(addr); + dummy = chb_xfer_byte(val); + + CHB_SPI_DISABLE(); + CHB_LEAVE_CRIT(); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_reg_write16(U8 addr, U16 val) +{ + U8 i; + + for (i=0; i<2; i++) + { + chb_reg_write(addr + i, val >> (8 * i)); + } +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_reg_write64(U8 addr, U8 *val) +{ + U8 i; + + for (i=0; i<8; i++) + { + chb_reg_write(addr + i, *(val + i)); + } +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask) +{ + U8 tmp; + + tmp = chb_reg_read(addr); + val &= mask; // mask off stray bits from val + tmp &= ~mask; // mask off bits in reg val + tmp |= val; // copy val into reg val + chb_reg_write(addr, tmp); // write back to reg +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len) +{ + U8 i, dummy; + + // dont allow transmission longer than max frame size + if ((hdr_len + data_len) > 127) + { + return; + } + + // initiate spi transaction + CHB_ENTER_CRIT(); + CHB_SPI_ENABLE(); + + // send fifo write command + dummy = chb_xfer_byte(CHB_SPI_CMD_FW); + + // write hdr contents to fifo + for (i=0; i= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH)) + { + // check to see if there is room to write the frame in the buffer. if not, then drop it + if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len())) + { + chb_buf_write(len); + + for (i=0; ioverflow++; + + // print the error message + printf(chb_err_overflow); + } + } + + CHB_SPI_DISABLE(); + CHB_LEAVE_CRIT(); +} + +/**************************************************************************/ +/*! + Read directly from the SRAM on the radio. This is only used for debugging + purposes. +*/ +/**************************************************************************/ +#ifdef CHB_DEBUG +void chb_sram_read(U8 addr, U8 len, U8 *data) +{ + U8 i, dummy; + + CHB_ENTER_CRIT(); + CHB_SPI_ENABLE(); + + /*Send SRAM read command.*/ + dummy = chb_xfer_byte(CHB_SPI_CMD_SR); + + /*Send address where to start reading.*/ + dummy = chb_xfer_byte(addr); + + for (i=0; i 3) + { + channel = 0; + } + + channel = (channel << 1) + 11; + + chb_reg_read_mod_write(CC_CTRL_1, 0x4, 0x7); // set 769 MHz base frequency for China + chb_reg_write(CC_CTRL_0, channel); // set the center frequency for the channel + +#else + //if (channel == 0) + //{ + // // Channel 0 is for European use only. make sure we are using channel page 2, + // // channel 0 settings for 100 kbps + // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08) + // { + // chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f); + // } + //} + //else if (channel > 10) + //{ + // // if the channel is out of bounds for page 2, then default to channel 1 and + // // assume we're on the US frequency of 915 MHz + // channel = 1; + // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c) + // { + // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f); + // } + //} + //else + //{ + // // Channels 1-10 are for US frequencies of 915 MHz + // if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c) + // { + // chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f); + // } + //} + + chb_reg_read_mod_write(PHY_CC_CCA, channel, 0x1f); +#endif + + // add a delay to allow the PLL to lock if in active mode. + state = chb_get_state(); + if ((state == RX_ON) || (state == PLL_ON)) + { + chb_delay_us(TIME_PLL_LOCK_TIME); + } + + return ((chb_reg_read(PHY_CC_CCA) & 0x1f) == channel) ? RADIO_SUCCESS : RADIO_TIMED_OUT; +} + +/**************************************************************************/ +/*! + Set the power level +*/ +/**************************************************************************/ +void chb_set_pwr(U8 val) +{ + chb_reg_write(PHY_TX_PWR, val); +} + +/**************************************************************************/ +/*! + Set the TX/RX state machine state. Some manual manipulation is required + for certain operations. Check the datasheet for more details on the state + machine and manipulations. +*/ +/**************************************************************************/ +U8 chb_set_state(U8 state) +{ + U8 curr_state, delay; + + // if we're sleeping then don't allow transition + if (gpioGetValue(CHB_SLPTRPORT, CHB_SLPTRPIN)) + { + return RADIO_WRONG_STATE; + } + + // if we're in a transition state, wait for the state to become stable + curr_state = chb_get_state(); + if ((curr_state == BUSY_TX_ARET) || (curr_state == BUSY_RX_AACK) || (curr_state == BUSY_RX) || (curr_state == BUSY_TX)) + { + while (chb_get_state() == curr_state); + } + + // At this point it is clear that the requested new_state is: + // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON. + // we need to handle some special cases before we transition to the new state + switch (state) + { + case TRX_OFF: + /* Go to TRX_OFF from any state. */ + CHB_SLPTR_DISABLE(); + chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1f); + chb_delay_us(TIME_ALL_STATES_TRX_OFF); + break; + + case TX_ARET_ON: + if (curr_state == RX_AACK_ON) + { + /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */ + chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f); + chb_delay_us(TIME_RX_ON_PLL_ON); + } + break; + + case RX_AACK_ON: + if (curr_state == TX_ARET_ON) + { + /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */ + chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f); + chb_delay_us(TIME_RX_ON_PLL_ON); + } + break; + } + + /* Now we're okay to transition to any new state. */ + chb_reg_read_mod_write(TRX_STATE, state, 0x1f); + + /* When the PLL is active most states can be reached in 1us. However, from */ + /* TRX_OFF the PLL needs time to activate. */ + delay = (curr_state == TRX_OFF) ? TIME_TRX_OFF_PLL_ON : TIME_RX_ON_PLL_ON; + chb_delay_us(delay); + + if (chb_get_state() == state) + { + return RADIO_SUCCESS; + } + return RADIO_TIMED_OUT; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_set_ieee_addr(U8 *addr) +{ + chb_eeprom_write(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8); + chb_reg_write64(IEEE_ADDR_0, addr); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_get_ieee_addr(U8 *addr) +{ + chb_eeprom_read(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_set_short_addr(U16 addr) +{ + U8 *addr_ptr = (U8 *)&addr; + chb_pcb_t *pcb = chb_get_pcb(); + + chb_eeprom_write(CFG_EEPROM_CHIBI_SHORTADDR, addr_ptr, 2); + chb_reg_write16(SHORT_ADDR_0, addr); + pcb->src_addr = addr; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +U16 chb_get_short_addr() +{ + int16_t addr; + + chb_eeprom_read(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t*)&addr, 2); + return addr; +} +/**************************************************************************/ +/*! + Set the high gain mode pin for the CC1190 +*/ +/**************************************************************************/ +#if (CHB_CC1190_PRESENT) +void chb_set_hgm(U8 enb) +{ + if (enb) + { + gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 1); + } + else + { + gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 0); + } +} +#endif + +/**************************************************************************/ +/*! + Load the data into the fifo, initiate a transmission attempt, + and return the status of the transmission attempt. +*/ +/**************************************************************************/ +U8 chb_tx(U8 *hdr, U8 *data, U8 len) +{ + U8 state = chb_get_state(); + chb_pcb_t *pcb = chb_get_pcb(); + + if ((state == BUSY_TX) || (state == BUSY_TX_ARET)) + { + return RADIO_WRONG_STATE; + } + + // TODO: check why we need to transition to the off state before we go to tx_aret_on + chb_set_state(TRX_OFF); + chb_set_state(TX_ARET_ON); + + // TODO: try and start the frame transmission by writing TX_START command instead of toggling + // sleep pin...i just feel like it's kind of weird... + + // write frame to buffer. first write header into buffer (add 1 for len byte), then data. + chb_frame_write(hdr, CHB_HDR_SZ + 1, data, len); + + //Do frame transmission + chb_reg_read_mod_write(TRX_STATE, CMD_TX_START, 0x1F); + + // wait for the transmission to end, signalled by the TRX END flag + while (!pcb->tx_end); + pcb->tx_end = false; + + // check the status of the transmission + return chb_get_status(); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +static void chb_radio_init() +{ + U8 ieee_addr[8]; + + // reset chip + chb_reset(); + + // disable intps while we config the radio + chb_reg_write(IRQ_MASK, 0); + + // force transceiver off while we configure the intps + chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1F); + + // make sure the transceiver is in the off state before proceeding + while ((chb_reg_read(TRX_STATUS) & 0x1f) != TRX_OFF); + + // set radio cfg parameters + // **note** uncomment if these will be set to something other than default + //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS); + //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS); + //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS); + //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0); + //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS); + //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES); + + // set frame version that we'll accept + chb_reg_read_mod_write(CSMA_SEED_1, CHB_FRM_VER << CHB_FVN_POS, 3 << CHB_FVN_POS); + + // set interrupt mask + // re-enable intps while we config the radio + chb_reg_write(IRQ_MASK, (1<ed = chb_reg_read(PHY_ED_LEVEL); + + // get the crc + pcb->crc = (chb_reg_read(PHY_RSSI) & (1<<7)) ? 1 : 0; + + // if the crc is not valid, then do not read the frame and set the rx flag + if (pcb->crc) + { + // get the data + chb_frame_read(); + pcb->rcvd_xfers++; + pcb->data_rcv = true; + } + } + else + { + pcb->tx_end = true; + } + intp_src &= ~CHB_IRQ_TRX_END_MASK; + while (chb_set_state(RX_STATE) != RADIO_SUCCESS); + } + else if (intp_src & CHB_IRQ_TRX_UR_MASK) + { + intp_src &= ~CHB_IRQ_TRX_UR_MASK; + pcb->underrun++; + } + else if (intp_src & CHB_IRQ_PLL_UNLOCK_MASK) + { + intp_src &= ~CHB_IRQ_PLL_UNLOCK_MASK; + } + else if (intp_src & CHB_IRQ_PLL_LOCK_MASK) + { + intp_src &= ~CHB_IRQ_PLL_LOCK_MASK; + } + else if (intp_src & CHB_IRQ_BAT_LOW_MASK) + { + intp_src &= ~CHB_IRQ_BAT_LOW_MASK; + pcb->battlow++; + } + else + { + } + } + CHB_LEAVE_CRIT(); +} diff --git a/drivers/chibi/chb_drvr.h b/drivers/chibi/chb_drvr.h new file mode 100644 index 0000000..48990bb --- /dev/null +++ b/drivers/chibi/chb_drvr.h @@ -0,0 +1,374 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +#ifndef CHIBI_DRVR_H +#define CHIBI_DRVR_H + +#include "types.h" +#include "projectconfig.h" +#include "core/gpio/gpio.h" + +#define CHB_CC1190_PRESENT 0 /// Set to 1 if CC1190 is being used +#define CHB_CHINA 0 +#define CHB_EEPROM_IEEE_ADDR CFG_CHIBI_EEPROM_IEEEADDR +#define CHB_EEPROM_SHORT_ADDR CFG_CHIBI_EEPROM_SHORTADDR +#define CHB_AT86RF212_VER_NUM 0x01 +#define CHB_AT86RF212_PART_NUM 0x07 +// #define CHB_BPSK 0 // set to 1 if want to use BPSK rather than OQPSK + +#define CHB_SPI_CMD_RW 0xC0 /**< Register Write (short mode). */ +#define CHB_SPI_CMD_RR 0x80 /**< Register Read (short mode). */ +#define CHB_SPI_CMD_FW 0x60 /**< Frame Transmit Mode (long mode). */ +#define CHB_SPI_CMD_FR 0x20 /**< Frame Receive Mode (long mode). */ +#define CHB_SPI_CMD_SW 0x40 /**< SRAM Write. */ +#define CHB_SPI_CMD_SR 0x00 /**< SRAM Read. */ +#define CHB_SPI_CMD_RADDRM 0x7F /**< Register Address Mask. */ + +#define CHB_IRQ_BAT_LOW_MASK 0x80 /**< Mask for the BAT_LOW interrupt. */ +#define CHB_IRQ_TRX_UR_MASK 0x40 /**< Mask for the TRX_UR interrupt. */ +#define CHB_IRQ_TRX_END_MASK 0x08 /**< Mask for the TRX_END interrupt. */ +#define CHB_IRQ_RX_START_MASK 0x04 /**< Mask for the RX_START interrupt. */ +#define CHB_IRQ_PLL_UNLOCK_MASK 0x02 /**< Mask for the PLL_UNLOCK interrupt. */ +#define CHB_IRQ_PLL_LOCK_MASK 0x01 /**< Mask for the PLL_LOCK interrupt. */ + +#define CHB_EINTPORT 1 +#define CHB_EINTPIN 8 +#define CHB_EINTPIN_IOCONREG IOCON_PIO1_8 +#define CHB_RSTPORT 1 +#define CHB_RSTPIN 9 +#define CHB_RSTPIN_IOCONREG IOCON_PIO1_9 +#define CHB_SLPTRPORT 1 +#define CHB_SLPTRPIN 10 +#define CHB_SLPTRPIN_IOCONREG IOCON_PIO1_10 + +// if CC1190 present, set up the ports and pins for high gain mode control +#if (CHB_CC1190_PRESENT) + #define CHB_CC1190_HGM_PORT 1 + #define CHB_CC1190_HGM_PIN 11 + #define CHB_CC1190_HGM_IOCONREG IOCON_PIO1_11 +#endif + +//#define CHB_DDR_SLPTR DDRF +//#define CHB_DDR_RST DDRF +//#define CHB_RADIO_IRQ INT6_vect +//#define CHB_RADIO_IRQ_PIN INT6 + +#define CHB_ENTER_CRIT() __disable_irq() +#define CHB_LEAVE_CRIT() __enable_irq() +#define CHB_RST_ENABLE() do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 0); } while (0) +#define CHB_RST_DISABLE() do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1); } while (0) +#define CHB_SLPTR_ENABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1); } while (0) +#define CHB_SLPTR_DISABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 0); } while (0) + +// CCA constants +enum +{ + CCA_ED = 1, /**< Use energy detection above threshold mode. */ + CCA_CARRIER_SENSE = 2, /**< Use carrier sense mode. */ + CCA_CARRIER_SENSE_WITH_ED = 3 /**< Use a combination of both energy detection and carrier sense. */ +}; + +// configuration parameters +enum +{ + CHB_CHANNEL = 1, // Replaced in projectconfig.h with CFG_CHIBI_CHANNEL + CHB_PAN_ID = 0x1234, // Replaced in projectconfig.h with CFG_CHIBI_PANID + CHB_TX_PWR = 0x0, + CHB_SHORT_ADDR = 0x0, + CHB_IEEE_ADDR = 0x0, + CHB_MAX_FRAME_RETRIES = 3, + CHB_MAX_CSMA_RETRIES = 4, + CHB_CCA_MODE = CCA_ED, + CHB_MIN_BE = 3, + CHB_MAX_BE = 5, + CHB_CCA_ED_THRES = 0x7, + CHB_CSMA_SEED0 = 0, + CHB_CSMA_SEED1 = 0, + CHB_FRM_VER = 1 // accept 802.15.4 ver 0 or 1 frames +}; + +// register addresses +enum +{ + TRX_STATUS = 0x01, + TRX_STATE = 0x02, + TRX_CTRL_0 = 0x03, + TRX_CTRL_1 = 0x04, + PHY_TX_PWR = 0x05, + PHY_RSSI = 0x06, + PHY_ED_LEVEL = 0x07, + PHY_CC_CCA = 0x08, + CCA_THRES = 0x09, + RX_CTRL = 0x0a, + SFD_VALUE = 0x0b, + TRX_CTRL_2 = 0x0c, + ANT_DIV = 0x0d, + IRQ_MASK = 0x0e, + IRQ_STATUS = 0x0f, + VREG_CTRL = 0x10, + BATMON = 0x11, + XOSC_CTRL = 0x12, + CC_CTRL_0 = 0x13, + CC_CTRL_1 = 0x14, + RX_SYN = 0x15, + RF_CTRL_0 = 0x16, + XAH_CTRL_1 = 0x17, + FTN_CTRL = 0x18, + RF_CTRL_1 = 0x19, + PLL_CF = 0x1a, + PLL_DCU = 0x1b, + PART_NUM = 0x1c, + VERSION_NUM = 0x1d, + MAN_ID_0 = 0x1e, + MAN_ID_1 = 0x1f, + SHORT_ADDR_0 = 0x20, + SHORT_ADDR_1 = 0x21, + PAN_ID_0 = 0x22, + PAN_ID_1 = 0x23, + IEEE_ADDR_0 = 0x24, + IEEE_ADDR_1 = 0x25, + IEEE_ADDR_2 = 0x26, + IEEE_ADDR_3 = 0x27, + IEEE_ADDR_4 = 0x28, + IEEE_ADDR_5 = 0x29, + IEEE_ADDR_6 = 0x2a, + IEEE_ADDR_7 = 0x2b, + XAH_CTRL_0 = 0x2c, + CSMA_SEED_0 = 0x2d, + CSMA_SEED_1 = 0x2e, + CSMA_BE = 0x2f +}; + +// random defines +enum +{ + CHB_MAX_FRAME_RETRIES_POS = 4, + CHB_MAX_CSMA_RETIRES_POS = 1, + CHB_CSMA_SEED1_POS = 0, + CHB_CCA_MODE_POS = 5, + CHB_AUTO_CRC_POS = 5, + CHB_TRX_END_POS = 3, + CHB_TRAC_STATUS_POS = 5, + CHB_FVN_POS = 6, + CHB_OQPSK_TX_OFFSET = 2, + CHB_BPSK_TX_OFFSET = 3, + CHB_MIN_FRAME_LENGTH = 3, + CHB_MAX_FRAME_LENGTH = 0x7f, + CHB_PA_EXT_EN_POS = 7 +}; + +// transceiver timing +enum{ + TIME_RST_PULSE_WIDTH = 1, + TIME_P_ON_TO_CLKM_AVAIL = 380, + TIME_SLEEP_TO_TRX_OFF = 240, + TIME_TRX_OFF_TO_SLEEP = 35, + TIME_PLL_ON_TRX_OFF = 1, + TIME_TRX_OFF_RX_ON = 110, + TIME_RX_ON_TRX_OFF = 1, + TIME_PLL_ON_RX_ON = 1, + TIME_RX_ON_PLL_ON = 1, + TIME_PLL_LOCK_TIME = 110, + TIME_BUSY_TX_PLL_ON = 32, + TIME_ALL_STATES_TRX_OFF = 1, + TIME_RESET_TRX_OFF = 26, + TIME_TRX_IRQ_DELAY = 9, + TIME_TRX_OFF_PLL_ON = 110, + TIME_IRQ_PROCESSING_DLY = 32 +}; + +// trac status +enum{ + TRAC_SUCCESS = 0, + TRAC_SUCCESS_DATA_PENDING = 1, + TRAC_WAIT_FOR_ACK = 2, + TRAC_CHANNEL_ACCESS_FAIL = 3, + TRAC_NO_ACK = 5, + TRAC_INVALID = 7 +}; + +// radio statuses +enum{ + RADIO_SUCCESS = 0x40, /**< The requested service was performed successfully. */ + RADIO_UNSUPPORTED_DEVICE, /**< The connected device is not an Atmel AT86RF212. */ + RADIO_INVALID_ARGUMENT, /**< One or more of the supplied function arguments are invalid. */ + RADIO_TIMED_OUT, /**< The requested service timed out. */ + RADIO_WRONG_STATE, /**< The end-user tried to do an invalid state transition. */ + RADIO_BUSY_STATE, /**< The radio transceiver is busy receiving or transmitting. */ + RADIO_STATE_TRANSITION_FAILED, /**< The requested state transition could not be completed. */ + RADIO_CCA_IDLE, /**< Channel is clear, available to transmit a new frame. */ + RADIO_CCA_BUSY, /**< Channel busy. */ + RADIO_TRX_BUSY, /**< Transceiver is busy receiving or transmitting data. */ + RADIO_BAT_LOW, /**< Measured battery voltage is lower than voltage threshold. */ + RADIO_BAT_OK, /**< Measured battery voltage is above the voltage threshold. */ + RADIO_CRC_FAILED, /**< The CRC failed for the actual frame. */ + RADIO_CHANNEL_ACCESS_FAILURE, /**< The channel access failed during the auto mode. */ + RADIO_NO_ACK, /**< No acknowledge frame was received. */ +}; + +// transceiver commands +enum +{ + CMD_NOP = 0, + CMD_TX_START = 2, + CMD_FORCE_TRX_OFF = 3, + CMD_FORCE_PLL_ON = 4, + CMD_RX_ON = 6, + CMD_TRX_OFF = 8, + CMD_PLL_ON = 9, + CMD_RX_AACK_ON = 22, + CMD_TX_ARET_ON = 25 +}; + +// transceiver states +enum +{ + P_ON = 0, + BUSY_RX = 1, + BUSY_TX = 2, + RX_ON = 6, + TRX_OFF = 8, + PLL_ON = 9, + SLEEP = 15, + BUSY_RX_AACK = 17, + BUSY_TX_ARET = 18, + RX_AACK_ON = 22, + TX_ARET_ON = 25, + RX_ON_NOCLK = 28, + RX_AACK_ON_NOCLK = 29, + BUSY_RX_AACK_NOCLK = 30, + TRANS_IN_PROG = 31 +}; + +// transceiver interrupt register +enum +{ + IRQ_PLL_LOCK = 0, + IRQ_PLL_UNLOCK = 1, + IRQ_RX_START = 2, + IRQ_TRX_END = 3, + IRQ_CCA_ED_READY = 4, + IRQ_AMI = 5, + IRQ_TRX_UR = 6, + IRQ_BAT_LOW = 7 +}; + +// transceiver modes +enum +{ + OQPSK_868MHZ = 0, + OQPSK_915MHZ = 1, + OQPSK_780MHZ = 2, + BPSK40_915MHZ = 3, + BPSK20_868MHZ = 4 +}; + +// See Table 7-15 for details +enum +{ + CHB_PWR_EU1_2DBM = 0x63, // EU (868MHz) Linearized PA mode + CHB_PWR_EU1_1DBM = 0x64, // Note: BPSK 20kbit/s only! + CHB_PWR_EU1_0DBM = 0x65, + CHB_PWR_EU2_5DBM = 0xE7, // EU (868MHz) Boost mode (but > supply current) + CHB_PWR_EU2_4DBM = 0xE8, // 4-5dBM BPSK 20 kbit/s only! + CHB_PWR_EU2_3DBM = 0xE9, // 0-3dBM O-QPSK 100/200/400 kbit/s or BPSK + CHB_PWR_EU2_2DBM = 0xEA, + CHB_PWR_EU2_1DBM = 0xCB, + CHB_PWR_EU2_0DBM = 0xAB, + CHB_PWR_NA_10DBM = 0xC0, // North America (915MHz) + CHB_PWR_NA_9DBM = 0xA1, + CHB_PWR_NA_8DBM = 0x81, + CHB_PWR_NA_7DBM = 0x82, + CHB_PWR_NA_6DBM = 0x83, + CHB_PWR_NA_5DBM = 0x60, + CHB_PWR_NA_4DBM = 0x61, + CHB_PWR_NA_3DBM = 0x41, + CHB_PWR_NA_2DBM = 0x42, + CHB_PWR_NA_1DBM = 0x22, + CHB_PWR_NA_0DBM = 0x23, + CHB_PWR_CHINA_5DBM = 0xE7, // China (780MHz) + CHB_PWR_CHINA_4DBM = 0xE8, + CHB_PWR_CHINA_3DBM = 0xE9, + CHB_PWR_CHINA_2DBM = 0xEA, + CHB_PWR_CHINA_1DBM = 0xCA, + CHB_PWR_CHINA_0DBM = 0xAA +}; + +// define receive state based on promiscuous mode setting +#if (CFG_CHIBI_PROMISCUOUS == 1) + #define RX_STATE RX_ON +#else + #define RX_STATE RX_AACK_ON +#endif +// init +void chb_drvr_init(); + +// data access +U8 chb_reg_read(U8 addr); +U16 chb_reg_read16(U8 addr); +void chb_reg_write(U8 addr, U8 val); +void chb_reg_write16(U8 addr, U16 val); +void chb_reg_write64(U8 addr, U8 *val); +void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask); +void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len); + +// general configuration +void chb_set_mode(U8 mode); +U8 chb_set_channel(U8 channel); +void chb_set_pwr(U8 val); +void chb_set_ieee_addr(U8 *addr); +void chb_get_ieee_addr(U8 *addr); +void chb_set_short_addr(U16 addr); +U16 chb_get_short_addr(); +U8 chb_set_state(U8 state); + +// Power management +void chb_sleep(U8 enb); + +// data transmit +U8 chb_tx(U8 *hdr, U8 *data, U8 len); + +#if (CHB_CC1190_PRESENT) + void chb_set_hgm(U8 enb); +#endif + +#ifdef CHB_DEBUG +// sram access +void chb_sram_read(U8 addr, U8 len, U8 *data); +void chb_sram_write(U8 addr, U8 len, U8 *data); +#endif + +void chb_ISR_Handler (void); + +#endif + diff --git a/drivers/chibi/chb_eeprom.c b/drivers/chibi/chb_eeprom.c new file mode 100644 index 0000000..d7e5f09 --- /dev/null +++ b/drivers/chibi/chb_eeprom.c @@ -0,0 +1,70 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +/*! + \file + \ingroup + + +*/ +/**************************************************************************/ +#include "chb_eeprom.h" +#include "drivers/eeprom/eeprom.h" + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_eeprom_write(uint16_t addr, uint8_t *buf, uint16_t size) +{ + // Write the address one byte at a time + uint16_t a = 0; + while (a < size) + { + eepromWriteU8(addr + a, buf[a]); + a++; + } +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_eeprom_read(uint16_t addr, uint8_t *buf, uint16_t size) +{ + // Read the contents at address + eepromReadBuffer(addr, buf, size); +} + diff --git a/drivers/chibi/chb_eeprom.h b/drivers/chibi/chb_eeprom.h new file mode 100644 index 0000000..3c3df71 --- /dev/null +++ b/drivers/chibi/chb_eeprom.h @@ -0,0 +1,50 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +/*! + \file + \ingroup + + +*/ +/**************************************************************************/ +#ifndef CHB_EEPROM_H +#define CHB_EEPROM_H + +#include "projectconfig.h" +#include "types.h" + +void chb_eeprom_write(U16 addr, U8 *buf, U16 size); +void chb_eeprom_read(U16 addr, U8 *buf, U16 size); + +#endif diff --git a/drivers/chibi/chb_spi.c b/drivers/chibi/chb_spi.c new file mode 100644 index 0000000..e552184 --- /dev/null +++ b/drivers/chibi/chb_spi.c @@ -0,0 +1,77 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +/*! + \file + \ingroup + + +*/ +/**************************************************************************/ +#include "chb.h" +#include "chb_spi.h" +#include "core/ssp/ssp.h" + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void chb_spi_init() +{ + // initialise spi, high between frames and transition on trailing edge + sspInit(0, sspClockPolarity_High, sspClockPhase_FallingEdge); + + // set the slave select to idle + CHB_SPI_DISABLE(); +} + +/**************************************************************************/ +/*! + This function both reads and writes data. For write operations, include data + to be written as argument. For read ops, use dummy data as arg. Returned + data is read byte val. +*/ +/**************************************************************************/ +U8 chb_xfer_byte(U8 data) +{ + /* Move on only if NOT busy and TX FIFO not full */ + while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_MASK | SSP_SSP0SR_BSY_MASK)) != SSP_SSP0SR_TNF_NOTFULL); + SSP_SSP0DR = data; + + /* Wait until the busy bit is cleared and receive buffer is not empty */ + while ((SSP_SSP0SR & (SSP_SSP0SR_BSY_MASK | SSP_SSP0SR_RNE_MASK)) != SSP_SSP0SR_RNE_NOTEMPTY); + + // Read the queue + return SSP_SSP0DR; +} diff --git a/drivers/chibi/chb_spi.h b/drivers/chibi/chb_spi.h new file mode 100644 index 0000000..220feb7 --- /dev/null +++ b/drivers/chibi/chb_spi.h @@ -0,0 +1,62 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. + +*******************************************************************/ +/*! + \file + \ingroup + + +*/ +/**************************************************************************/ + +#ifndef CHB_SPI_H +#define CHB_SPI_H + +#include "projectconfig.h" +#include "core/gpio/gpio.h" + +#define CHB_SSPORT (0) // P0.2 = SSEL +#define CHB_SSPIN (2) + +#define CHB_SPI_ENABLE() do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 0);} while (0) // Drive SSEL low +#define CHB_SPI_DISABLE() do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 1);} while (0) // Drive SSEL high + +#define CHB_SPIPORT 0 +#define CHB_SCK 1 // PB.1 - Output: SPI Serial Clock (SCLK) +#define CHB_MOSI 2 // PB.2 - Output: SPI Master out - slave in (MOSI) +#define CHB_MISO 3 // PB.3 - Input: SPI Master in - slave out (MISO) + +void chb_spi_init(); +U8 chb_xfer_byte(U8 data); + +#endif diff --git a/drivers/chibi/types.h b/drivers/chibi/types.h new file mode 100644 index 0000000..c551bbc --- /dev/null +++ b/drivers/chibi/types.h @@ -0,0 +1,54 @@ +/******************************************************************* + Copyright (C) 2009 FreakLabs + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF + SUCH DAMAGE. + + Originally written by Christopher Wang aka Akiba. + Please post support questions to the FreakLabs forum. +*******************************************************************/ +/*! + \file types.h + \ingroup usb +*/ +/*******************************************************************/ +#ifndef TYPES_H +#define TYPES_H + +#include +#include + +// Standard data types +typedef uint8_t U8; /// Generic 8 bit unsigned data type +typedef uint16_t U16; /// Generic 16 bit unsigned data type +typedef uint32_t U32; /// Generic 32 bit unsigned data type +typedef uint64_t U64; /// Generic 64 bit unsigned data type + +typedef int8_t S8; /// Generic 8 bit signed data type +typedef int16_t S16; /// Generic 16 bit signed data type +typedef int32_t S32; /// Generic 32 bit signed data type + +#endif diff --git a/drivers/dac/mcp4725/mcp4725.c b/drivers/dac/mcp4725/mcp4725.c new file mode 100644 index 0000000..7b9c6ac --- /dev/null +++ b/drivers/dac/mcp4725/mcp4725.c @@ -0,0 +1,158 @@ +/**************************************************************************/ +/*! + @file mcp4725.c + @author K. Townsend (microBuilder.eu) + + @brief Driver for the I2C-based MCP4725 12-Bit DAC. + + @section Example + + @code + #include "drivers/dac/mcp4725/mcp4725.h" + ... + + mcp4725Init(); + + // Set the voltage to 50% of vref and don't save the value in EEPROM + mcp4725SetVoltage(2048, false); + + // Request the current value from the DAC + uint8_t status = 0; + uint16_t value = 0; + mcp472ReadConfig(&status, &value); + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "mcp4725.h" +#include "core/i2c/i2c.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +static bool _mcp4725Initialised = false; + +/**************************************************************************/ +/*! + @brief Initialises I2C for the MCP4725. +*/ +/**************************************************************************/ +int mcp4725Init() +{ + // Initialise I2C + if (i2cInit(I2CMASTER) == false) + { + /* Fatal error */ + return -1; + } + + /* Set initialisation flag */ + _mcp4725Initialised = true; + + return 0; +} + +/**************************************************************************/ +/*! + @brief Sets the output voltage to a fraction of source vref. (Value + can be 0..4095) + + @param[in] output + The 12-bit value representing the relationship between + the DAC's input voltage and its output voltage. + @param[in] writeEEPROM + If this value is true, 'output' will also be written + to the MCP4725's internal non-volatile memory, meaning + that the DAC will retain the current voltage output + after power-down or reset. +*/ +/**************************************************************************/ +void mcp4725SetVoltage( uint16_t output, bool writeEEPROM ) +{ + if (!_mcp4725Initialised) mcp4725Init(); + + // Clear write buffers + uint32_t i; + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 4; + I2CReadLength = 0; + I2CMasterBuffer[0] = MCP4725_ADDRESS; // I2C device address + if (writeEEPROM) // command and config bits (C2.C1.C0.x.x.PD1.PD0.x) + { + I2CMasterBuffer[1] = (MCP4726_CMD_WRITEDACEEPROM); + } + else + { + I2CMasterBuffer[1] = (MCP4726_CMD_WRITEDAC); + } + I2CMasterBuffer[2] = (output / 16); // Upper data bits (D11.D10.D9.D8.D7.D6.D5.D4) + I2CMasterBuffer[3] = (output % 16) << 4; // Lower data bits (D3.D2.D1.D0.x.x.x.x) + i2cEngine(); +} + +/**************************************************************************/ +/*! + @brief Reads the current configuration and output settings for the + DAC. + + @param[out] status + Pointer to hold the contents of the status register + @param[out] value + Pointer to hold the output value of the 12-bit DAC +*/ +/**************************************************************************/ +void mcp472ReadConfig( uint8_t *status, uint16_t *value ) +{ + if (!_mcp4725Initialised) mcp4725Init(); + + // Clear write buffers + uint32_t i; + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 1; + I2CReadLength = 3; + I2CMasterBuffer[0] = MCP4725_ADDRESS | MCP4725_READ; + i2cEngine(); + + // Shift values to create properly formed integers + *status = I2CSlaveBuffer[0]; + *value = ((I2CSlaveBuffer[1] << 4) | (I2CSlaveBuffer[2] >> 4)); +} + diff --git a/drivers/dac/mcp4725/mcp4725.h b/drivers/dac/mcp4725/mcp4725.h new file mode 100644 index 0000000..71100cc --- /dev/null +++ b/drivers/dac/mcp4725/mcp4725.h @@ -0,0 +1,51 @@ +/**************************************************************************/ +/*! + @file mcp4725.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _MCP4725_H_ +#define _MCP4725_H_ + +#include "projectconfig.h" + +#define MCP4725_ADDRESS (0xC0) // 1100000x - Assumes A0 is GND and A2,A1 are 0 (MCP4725A0T-E/CH) +#define MCP4725_READ (0x01) +#define MCP4726_CMD_WRITEDAC (0x40) // Writes data to the DAC +#define MCP4726_CMD_WRITEDACEEPROM (0x60) // Writes data to the DAC and the EEPROM (persisting the assigned value after reset) + +int mcp4725Init(); +void mcp4725SetVoltage( uint16_t output, bool writeEEPROM ); +void mcp472ReadConfig( uint8_t *status, uint16_t *value ); + +#endif \ No newline at end of file diff --git a/drivers/eeprom/at25040/at25040.c b/drivers/eeprom/at25040/at25040.c new file mode 100644 index 0000000..d84a733 --- /dev/null +++ b/drivers/eeprom/at25040/at25040.c @@ -0,0 +1,297 @@ +/**************************************************************************/ +/*! + @file at25040.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Driver for Atmel's AT25010a/AT25020a/AT25040a 1K/2K/4K serial EEPROM. + + @note The AT25xxx has an 8-byte buffer, including 1 command byte + and one address offset byte, meaning that a maximum of 6 + bytes can be read or written in one operation. An error + will be returned if a value greater than 6 is passed in + for bufferLength with the eepromRead and eepromWrite + methods. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "drivers/eeprom/at25040/at25040.h" + + int main(void) + { + cpuInit(); + at25Init(); + + // Set read and write buffers + uint8_t wBuffer[1]; + uint8_t rBuffer[1]; + + // Instantiate error message placeholder + at25Error_e error = AT25_ERROR_OK; + + // Write 0xAA to EEPROM at address 0x0000 + wBuffer[0] = 0xAA; + error = at25Write(0x0000, wBuffer, 1); + if (error) + { + // Log the error message or take appropriate actions + switch (error) + { + case (AT25_ERROR_TIMEOUT_WFINISH): + // EEPROM timed out waiting for the write to finish + break; + case (AT25_ERROR_TIMEOUT_WE): + // EEPROM timed out waiting for write-enable + break; + case (AT25_ERROR_ADDRERR): + // Address is out of range + break; + } + } + + // Read the EEPROM at address 0x0000 + at25Read(0x0000, rBuffer, 1); + ... + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "at25040.h" +#include "core/ssp/ssp.h" +#include "core/gpio/gpio.h" + +#define AT25_SELECT() gpioSetValue(0, 2, 0) +#define AT25_DESELECT() gpioSetValue(0, 2, 1) + +uint32_t i, timeout; +uint8_t src_addr[SSP_FIFOSIZE]; +uint8_t dest_addr[SSP_FIFOSIZE]; + +/**************************************************************************/ +/*! + @brief Sends the write enable command (WREN/0x06) +*/ +/**************************************************************************/ +void at25WriteEnable() +{ + AT25_SELECT(); + src_addr[0] = AT25_WREN; + sspSend(0, (uint8_t *)src_addr, 1); + AT25_DESELECT(); + + // Delay for at least 250nS (1nS @ 72MHz = ~0.0072 ticks) + for (i = 0; i < 100; i++); +} + +/**************************************************************************/ +/*! + @brief Gets the value of the Read Status Register (RDSR/0x05) + + @return The 8-bit value returned by the Read Status Register +*/ +/**************************************************************************/ +uint8_t at25GetRSR() +{ + AT25_SELECT(); + src_addr[0] = AT25_RDSR; + sspSend(0, (uint8_t *)src_addr, 1); + sspReceive(0, (uint8_t *)dest_addr, 1); + AT25_DESELECT(); + return dest_addr[0] & (AT25_RDSR_WEN | AT25_RDSR_RDY); +} + +/**************************************************************************/ +/*! + @brief Initialises the SPI block (CLK set low when inactive, trigger + on leading edge). +*/ +/**************************************************************************/ +void at25Init (void) +{ + sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge); +} + +/**************************************************************************/ +/*! + @brief Reads the specified number of bytes from the supplied address. + + This function will read one or more bytes starting at the supplied + address. + + @param[in] address + The 16-bit address where the read will start. The maximum + value for the address depends on the size of the EEPROM + @param[in] *buffer + Pointer to the buffer that will store the read results + @param[in] bufferLength + Length of the buffer +*/ +/**************************************************************************/ +at25Error_e at25Read (uint16_t address, uint8_t *buffer, uint32_t bufferLength) +{ + if (address >= AT25_MAXADDRESS) + { + return AT25_ERROR_ADDRERR; + } + + if (bufferLength > 6) + { + return AT25_ERROR_BUFFEROVERFLOW; + } + + timeout = 0; + while ( timeout < SSP_MAX_TIMEOUT ) + { + // Wait until the device is ready + uint8_t status = at25GetRSR() & AT25_RDSR_RDY; + if (status == 0) + { + break; + } + timeout++; + } + if ( timeout == SSP_MAX_TIMEOUT ) + { + return AT25_ERROR_TIMEOUT_WE; + } + + AT25_SELECT(); + // Read command (0x03), append A8 if > addr 256 bytes + src_addr[0] = address > 0xFF ? AT25_READ | AT25_A8 : AT25_READ; + src_addr[1] = (address); + sspSend(0, (uint8_t *)src_addr, 2); + sspReceive(0, (uint8_t *)&dest_addr[2], bufferLength); + AT25_DESELECT(); + + // Fill response buffer + for (i = 0; i < bufferLength; i++) + { + buffer[i] = dest_addr[i + 2]; + } + + return AT25_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Writes the supplied bytes at a specified address. + + This function will write one or more bytes starting at the supplied + address. + + @param[in] address + The 16-bit address where the write will start. The + maximum value for the address depends on the size of the + EEPROM + @param[in] *buffer + Pointer to the buffer that contains the values to write. + @param[in] bufferLength + Length of the buffer +*/ +/**************************************************************************/ +at25Error_e at25Write (uint16_t address, uint8_t *buffer, uint32_t bufferLength) +{ + if (address >= AT25_MAXADDRESS) + { + return AT25_ERROR_ADDRERR; + } + + if (bufferLength > 6) + { + return AT25_ERROR_BUFFEROVERFLOW; + } + + // Set write enable latch + at25WriteEnable(); + + timeout = 0; + while ( timeout < SSP_MAX_TIMEOUT ) + { + // Wait until the device is write enabled + if (at25GetRSR() == AT25_RDSR_WEN) + { + break; + } + timeout++; + } + if ( timeout == SSP_MAX_TIMEOUT ) + { + return AT25_ERROR_TIMEOUT_WE; + } + + for (i = 0; i < bufferLength; i++) // Init RD and WR buffer + { + src_addr[i+2] = buffer[i]; // leave two bytes for cmd and offset(8 bits) + dest_addr[i] = 0; + } + + AT25_SELECT(); + // Write command (0x02), append A8 if addr > 256 bytes + src_addr[0] = address > 0xFF ? AT25_WRITE | AT25_A8 : AT25_WRITE; + src_addr[1] = (address); + sspSend(0, (uint8_t *)src_addr, bufferLength + 2); + AT25_DESELECT(); + + // Wait at least 3ms + for (i = 0; i < ((CFG_CPU_CCLK / 1000) * 3); i++); + + timeout = 0; + while ( timeout < SSP_MAX_TIMEOUT ) + { + // Check status to see if write cycle is done or not + AT25_SELECT(); + src_addr[0] = AT25_RDSR; + sspSend(0, (uint8_t *)src_addr, 1); + sspReceive(0, (uint8_t *)dest_addr, 1); + AT25_DESELECT(); + // Wait until device is ready + if ((dest_addr[0] & AT25_RDSR_RDY) == 0x00) + { + break; + } + timeout++; + } + if ( timeout == SSP_MAX_TIMEOUT ) + { + return AT25_ERROR_TIMEOUT_WFINISH; + } + + for (i = 0; i < 300; i++); // Wait at least 250ns + + return AT25_ERROR_OK; +} diff --git a/drivers/eeprom/at25040/at25040.h b/drivers/eeprom/at25040/at25040.h new file mode 100644 index 0000000..57a6d6d --- /dev/null +++ b/drivers/eeprom/at25040/at25040.h @@ -0,0 +1,85 @@ +/**************************************************************************/ +/*! + @file at25040.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _AT25040_H_ +#define _AT25040_H_ + +#include "projectconfig.h" + +#define AT25_RDSR_RDY 0x01 +#define AT25_RDSR_WEN 0x02 +#define AT25_A8 0x08 // For addresses > 0xFF (AT25040 only) A8 must be added to R/W commands +#define AT25_MAXADDRESS 0x0200 // AT25040 = 0X0200, AT25020 = 0x100, AT25010 = 0x80 + +/**************************************************************************/ +/*! + AT25040 Commands +*/ +/**************************************************************************/ +typedef enum +{ + AT25_WREN = 0x06, + AT25_WRDI = 0x04, + AT25_RDSR = 0x05, + AT25_WRSR = 0x01, + AT25_READ = 0x03, + AT25_WRITE = 0x02 +} at25_Commands_e; + +/**************************************************************************/ +/*! + Error messages +*/ +/**************************************************************************/ +typedef enum +{ + AT25_ERROR_OK = 0, // Everything executed normally + AT25_ERROR_TIMEOUT_WE, // Timed out waiting for write enable status + AT25_ERROR_TIMEOUT_WFINISH, // Timed out waiting for write to finish + AT25_ERROR_ADDRERR, // Address out of range + AT25_ERROR_BUFFEROVERFLOW, // Max 6 bytes can be read/written in one operation + AT2_ERROR_LAST +} +at25Error_e; + +void at25Init (void); +at25Error_e at25Read (uint16_t address, uint8_t *buffer, uint32_t bufferLength); +at25Error_e at25Write (uint16_t address, uint8_t *buffer, uint32_t bufferLength); + +#endif diff --git a/drivers/eeprom/eeprom.c b/drivers/eeprom/eeprom.c new file mode 100644 index 0000000..fda0d9b --- /dev/null +++ b/drivers/eeprom/eeprom.c @@ -0,0 +1,410 @@ +/**************************************************************************/ +/*! + @file eeprom.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "eeprom.h" + +// Currently only the MCP24AA I2C EEPROM is used +#include "drivers/eeprom/mcp24aa/mcp24aa.h" + +static uint8_t buf[32]; + +/**************************************************************************/ +/*! + @brief Checks whether the supplied address is within the valid range + + @param[in] addr + The 16-bit address to check + + @return Zero if the address is valid, otherwise 1 +*/ +/**************************************************************************/ +bool eepromCheckAddress(uint16_t addr) +{ + // Check for invalid values + return addr <= MCP24AA_MAXADDR ? FALSE : TRUE; +} + +/**************************************************************************/ +/*! + @brief Reads 1 byte from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return An unsigned 8-bit value (uint8_t) +*/ +/**************************************************************************/ +uint8_t eepromReadU8(uint16_t addr) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(uint8_t)); + + // ToDo: Handle any errors + if (error) { }; + + return buf[0]; +} + +/**************************************************************************/ +/*! + @brief Reads 1 byte from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A signed 8-bit value (int8_t) +*/ +/**************************************************************************/ +int8_t eepromReadS8(uint16_t addr) +{ + int8_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(int8_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(int8_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 2 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A unsigned 16-bit value (uint16_t) +*/ +/**************************************************************************/ +uint16_t eepromReadU16(uint16_t addr) +{ + uint16_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(uint16_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(uint16_t)); + + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 2 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A signed 16-bit value (int16_t) +*/ +/**************************************************************************/ +int16_t eepromReadS16(uint16_t addr) +{ + int16_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(int16_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(int16_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 4 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A unsigned 32-bit value (uint32_t) +*/ +/**************************************************************************/ +uint32_t eepromReadU32(uint16_t addr) +{ + uint32_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(uint32_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(uint32_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 4 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A signed 32-bit value (int32_t) +*/ +/**************************************************************************/ +int32_t eepromReadS32(uint16_t addr) +{ + int32_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(int32_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(int32_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 8 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A unsigned 64-bit value (uint64_t) +*/ +/**************************************************************************/ +uint64_t eepromReadU64(uint16_t addr) +{ + uint64_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(uint64_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(uint64_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads 8 bytes from EEPROM + + @param[in] addr + The 16-bit address to read from in EEPROM + + @return A signed 64-bit value (int64_t) +*/ +/**************************************************************************/ +int64_t eepromReadS64(uint16_t addr) +{ + int64_t results; + + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaReadBuffer(addr, buf, sizeof(int64_t)); + + // ToDo: Handle any errors + if (error) { }; + + memcpy(&results, buf, sizeof(int64_t)); + return results; +} + +/**************************************************************************/ +/*! + @brief Reads a variabls length buffer from EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM + @param[out] buffer + Pointer to the buffer that will store any retrieved bytes + @param[in] bufferLength + The number of bytes to read +*/ +/**************************************************************************/ +void eepromReadBuffer(uint16_t addr, uint8_t *buffer, uint32_t bufferLength) +{ + // Instantiate error message placeholder + mcp24aaError_e error = MCP24AA_ERROR_OK; + + // Read the contents of address + error = mcp24aaReadBuffer(addr, buffer, bufferLength); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes 1 byte to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteU8(uint16_t addr, uint8_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes 1 signed byte to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteS8(uint16_t addr, int8_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes an unsigned 16-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteU16(uint16_t addr, uint16_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes a signed 16-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteS16(uint16_t addr, int16_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes an unsigned 32-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteU32(uint16_t addr, uint32_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes a signed 32-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteS32(uint16_t addr, int32_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes an unsigned 64-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteU64(uint16_t addr, uint64_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} + +/**************************************************************************/ +/*! + @brief Writes a signed 64-bit integer to EEPROM + + @param[in] addr + The 16-bit address to write to in EEPROM +*/ +/**************************************************************************/ +void eepromWriteS64(uint16_t addr, int64_t value) +{ + mcp24aaError_e error = MCP24AA_ERROR_OK; + error = mcp24aaWriteBuffer(addr, (uint8_t *)&value, sizeof(value)); + + // ToDo: Handle any errors + if (error) { }; +} diff --git a/drivers/eeprom/eeprom.h b/drivers/eeprom/eeprom.h new file mode 100644 index 0000000..71875b7 --- /dev/null +++ b/drivers/eeprom/eeprom.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/*! + @file eeprom.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + +#include "projectconfig.h" + +// Method Prototypes +bool eepromCheckAddress ( uint16_t addr ); +uint8_t eepromReadU8 ( uint16_t addr ); +int8_t eepromReadS8 ( uint16_t addr ); +uint16_t eepromReadU16 ( uint16_t addr ); +int16_t eepromReadS16 ( uint16_t addr ); +uint32_t eepromReadU32 ( uint16_t addr ); +int32_t eepromReadS32 ( uint16_t addr ); +uint64_t eepromReadU64 ( uint16_t addr ); +int64_t eepromReadS64 ( uint16_t addr ); +void eepromReadBuffer ( uint16_t addr, uint8_t *buffer, uint32_t bufferLength); +void eepromWriteU8 ( uint16_t addr, uint8_t value ); +void eepromWriteS8 ( uint16_t addr, int8_t value ); +void eepromWriteU16 ( uint16_t addr, uint16_t value ); +void eepromWriteS16 ( uint16_t addr, int16_t value ); +void eepromWriteU32 ( uint16_t addr, uint32_t value ); +void eepromWriteS32 ( uint16_t addr, int32_t value ); +void eepromWriteU64 ( uint16_t addr, uint64_t value ); +void eepromWriteS64 ( uint16_t addr, int64_t value ); + +#endif diff --git a/drivers/eeprom/mcp24aa/mcp24aa.c b/drivers/eeprom/mcp24aa/mcp24aa.c new file mode 100644 index 0000000..f7f981d --- /dev/null +++ b/drivers/eeprom/mcp24aa/mcp24aa.c @@ -0,0 +1,339 @@ +/**************************************************************************/ +/*! + @file mcp24aa.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Driver for Microchip's 24AA32AF serial EEPROM. This driver assumes + that the address is set to 1010 000. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "drivers/eeprom/mcp24aa/mcp24aa.h" + + int main(void) + { + cpuInit(); + + mcp24aaInit(); + + // Instantiate error message placeholder + mcp24aaError_e error = MCP24AA_ERROR_OK; + + // Create read buffer (1 byte) + uint8_t buffer[1] = { 0x00 }; + + // Write 0xCC at address 0x125 + error = mcp24aaWriteByte(0x0125, 0xCC); + if (error) + { + // Handle any errors + switch (error) + { + case (MCP24AA_ERROR_I2CINIT): + // Unable to initialise I2C + break; + case (MCP24AA_ERROR_ADDRERR): + // Address out of range + break; + default: + break; + } + } + + // Read the contents of address 0x0125 + error = MCP24AA_ERROR_OK; + error = mcp24aaReadByte(0x0125, buffer); + if (error) + { + // Handle any errors + switch (error) + { + case (MCP24AA_ERROR_I2CINIT): + // Unable to initialise I2C + break; + case (MCP24AA_ERROR_ADDRERR): + // Address out of range + break; + default: + break; + } + } + + uint8_t results = buffer[0]; + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "mcp24aa.h" +#include "core/systick/systick.h" +#include "core/i2c/i2c.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +uint32_t i, timeout; + +static bool _mcp24aaInitialised = false; + +/**************************************************************************/ +/*! + @brief Initialises the I2C block +*/ +/**************************************************************************/ +mcp24aaError_e mcp24aaInit() +{ + // Initialise I2C + if (i2cInit(I2CMASTER) == false) + { + return MCP24AA_ERROR_I2CINIT; /* Fatal error */ + } + + // Set initialisation flag + _mcp24aaInitialised = true; + + return MCP24AA_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Reads the specified number of bytes from the supplied address. + + This function will read one or more bytes starting at the supplied + address. A maximum of 8 bytes can be read in one operation. + + @param[in] address + The 16-bit address where the read will start. The maximum + value for the address depends on the size of the EEPROM + @param[in] *buffer + Pointer to the buffer that will store the read results + @param[in] bufferLength + Length of the buffer +*/ +/**************************************************************************/ +mcp24aaError_e mcp24aaReadBuffer (uint16_t address, uint8_t *buffer, uint32_t bufferLength) +{ + if (!_mcp24aaInitialised) mcp24aaInit(); + + if (address >= MCP24AA_MAXADDR) + { + return MCP24AA_ERROR_ADDRERR; + } + + if (bufferLength > 8) + { + return MCP24AA_ERROR_BUFFEROVERFLOW; + } + + // ToDo: Check if I2C is ready + + // Clear buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + I2CSlaveBuffer[i] = 0x00; + } + + // Write address bits to enable random read + I2CWriteLength = 3; + I2CReadLength = bufferLength; + I2CMasterBuffer[0] = MCP24AA_ADDR; // I2C device address + I2CMasterBuffer[1] = (address >> 8); // Address (high byte) + I2CMasterBuffer[2] = (address & 0xFF); // Address (low byte) + // If you wish to read, you need to append the address w/read bit, though this + // needs to be placed one bit higher than the size of I2CWriteLength which + // may be unexpected + I2CMasterBuffer[3] = MCP24AA_ADDR | MCP24AA_READBIT; + + // Transmit command + i2cEngine(); + + // Fill response buffer + for (i = 0; i < bufferLength; i++) + { + buffer[i] = I2CSlaveBuffer[i]; + } + + return MCP24AA_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Writes the supplied bytes at a specified address. + + This function will write one or more bytes starting at the supplied + address. A maximum of 8 bytes can be written in one operation. + + @param[in] address + The 16-bit address where the write will start. The + maximum value for the address depends on the size of the + EEPROM + @param[in] *buffer + Pointer to the buffer that contains the values to write. + @param[in] bufferLength + Length of the buffer +*/ +/**************************************************************************/ +mcp24aaError_e mcp24aaWriteBuffer (uint16_t address, uint8_t *buffer, uint32_t bufferLength) +{ + if (!_mcp24aaInitialised) mcp24aaInit(); + + if (address >= MCP24AA_MAXADDR) + { + return MCP24AA_ERROR_ADDRERR; + } + + if (bufferLength > 8) + { + return MCP24AA_ERROR_BUFFEROVERFLOW; + } + + // ToDo: Check if I2C is ready + + // Clear write buffer + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + // Write address bits and data to the master buffer + I2CWriteLength = 3 + bufferLength; + I2CReadLength = 0; + I2CMasterBuffer[0] = MCP24AA_ADDR; // I2C device address + I2CMasterBuffer[1] = (address >> 8); // Address (high byte) + I2CMasterBuffer[2] = (address & 0xFF); // Address (low byte) + for (i = 0; i < bufferLength; i++) + { + I2CMasterBuffer[i+3] = buffer[i]; + } + + // Transmit command + i2cEngine(); + + // Wait at least 10ms + systickDelay(10); + + return MCP24AA_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Reads one byte from the supplied address. + + This function will read one byte starting at the supplied address. + + @param[in] address + The 16-bit address where the read will start. The maximum + value for the address depends on the size of the EEPROM + @param[in] *buffer + Pointer to the buffer that will store the read results + + @code + #include "core/cpu/cpu/h" + #include "drivers/eeprom/mcp24aa/mcp24aa.h" + ... + cpuInit(); + mcp24aaInit(); + + // Create read buffer (1 byte) + uint8_t buffer[1] = { 0x00 }; + + // Write 0xEE and address 0x0120 + mcp24aaWriteByte(0x0120, 0xEE); + + // Populate buffer with contents of 0x0120 + mcp24aaReadByte(0x0120, buffer); + + // results should equal 0xEE + uint8_t results = buffer[0]; + @endcode +*/ +/**************************************************************************/ +mcp24aaError_e mcp24aaReadByte (uint16_t address, uint8_t *buffer) +{ + if (!_mcp24aaInitialised) mcp24aaInit(); + + return mcp24aaReadBuffer(address, buffer, 1); +} + +/**************************************************************************/ +/*! + @brief Writes one byte to the supplied address. + + This function will write one byte at the supplied address. + + @param[in] address + The 16-bit address where the write will start. The maximum + value for the address depends on the size of the EEPROM + @param[in] value + The data to be written to the EEPROM + + @code + #include "core/cpu/cpu/h" + #include "drivers/eeprom/mcp24aa/mcp24aa.h" + ... + cpuInit(); + mcp24aaInit(); + + // Create read buffer (1 byte) + uint8_t buffer[1] = { 0x00 }; + + // Write 0xEE and address 0x0120 + mcp24aaWriteByte(0x0120, 0xEE); + + // Populate buffer with contents of 0x0120 + mcp24aaReadByte(0x0120, buffer); + + // results should equal 0xEE + uint8_t results = buffer[0]; + @endcode +*/ +/**************************************************************************/ +mcp24aaError_e mcp24aaWriteByte (uint16_t address, uint8_t value) +{ + if (!_mcp24aaInitialised) mcp24aaInit(); + + // Set read buffer + uint8_t wBuffer[1]; + + // Write byte to EEPROM at specified address + wBuffer[0] = value; + return mcp24aaWriteBuffer(address, wBuffer, 1); +} + diff --git a/drivers/eeprom/mcp24aa/mcp24aa.h b/drivers/eeprom/mcp24aa/mcp24aa.h new file mode 100644 index 0000000..3563939 --- /dev/null +++ b/drivers/eeprom/mcp24aa/mcp24aa.h @@ -0,0 +1,67 @@ +/**************************************************************************/ +/*! + @file mcp24aa.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _MCP24AA_H_ +#define _MCP24AA_H_ + +#include "projectconfig.h" + +#define MCP24AA_ADDR 0xA0 // 10100000 +#define MCP24AA_RW 0x01 +#define MCP24AA_READBIT 0x01 +#define MCP24AA_MAXADDR 0xFFF // 4K = 4096 + +typedef enum +{ + MCP24AA_ERROR_OK = 0, // Everything executed normally + MCP24AA_ERROR_I2CINIT, // Unable to initialise I2C + MCP24AA_ERROR_I2CBUSY, // I2C already in use + MCP24AA_ERROR_ADDRERR, // Address out of range + MCP24AA_ERROR_BUFFEROVERFLOW, // Max 8 bytes can be read/written in one operation + MCP24AA_ERROR_LAST +} +mcp24aaError_e; + +mcp24aaError_e mcp24aaInit (void); +mcp24aaError_e mcp24aaReadBuffer (uint16_t address, uint8_t *buffer, uint32_t bufferLength); +mcp24aaError_e mcp24aaWriteBuffer (uint16_t address, uint8_t *buffer, uint32_t bufferLength); +mcp24aaError_e mcp24aaReadByte (uint16_t address, uint8_t *buffer); +mcp24aaError_e mcp24aaWriteByte (uint16_t address, uint8_t value); + + +#endif diff --git a/drivers/fatfs/ccsbcs.c b/drivers/fatfs/ccsbcs.c new file mode 100644 index 0000000..f0d211e --- /dev/null +++ b/drivers/fatfs/ccsbcs.c @@ -0,0 +1,540 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */ +/* (SBCS code pages) */ +/*------------------------------------------------------------------------*/ +/* 437 U.S. (OEM) +/ 720 Arabic (OEM) +/ 1256 Arabic (Windows) +/ 737 Greek (OEM) +/ 1253 Greek (Windows) +/ 1250 Central Europe (Windows) +/ 775 Baltic (OEM) +/ 1257 Baltic (Windows) +/ 850 Multilingual Latin 1 (OEM) +/ 852 Latin 2 (OEM) +/ 1252 Latin 1 (Windows) +/ 855 Cyrillic (OEM) +/ 1251 Cyrillic (Windows) +/ 866 Russian (OEM) +/ 857 Turkish (OEM) +/ 1254 Turkish (Windows) +/ 858 Multilingual Latin 1 + Euro (OEM) +/ 862 Hebrew (OEM) +/ 1255 Hebrew (Windows) +/ 874 Thai (OEM, Windows) +/ 1258 Vietnam (OEM, Windows) +*/ + +#include "ff.h" + + +#if _CODE_PAGE == 437 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 720 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ + 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, + 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, + 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, + 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 737 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, + 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, + 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, + 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, + 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 775 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ + 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, + 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, + 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, + 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, + 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, + 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, + 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, + 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, + 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, + 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 850 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 852 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, + 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, + 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, + 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, + 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 855 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, + 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, + 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, + 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, + 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, + 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 857 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, + 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 858 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, + 0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE, + 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, + 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 862 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 866 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 874 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, + 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, + 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, + 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, + 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, + 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, + 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, + 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, + 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, + 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, + 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, + 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +#elif _CODE_PAGE == 1250 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, + 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B, + 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +}; + +#elif _CODE_PAGE == 1251 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */ + 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, + 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, + 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, + 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, + 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, + 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, + 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042D, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F +}; + +#elif _CODE_PAGE == 1252 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +}; + +#elif _CODE_PAGE == 1253 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000 +}; + +#elif _CODE_PAGE == 1254 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +}; + +#elif _CODE_PAGE == 1255 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, + 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, + 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, + 0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000 +}; + +#elif _CODE_PAGE == 1256 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, + 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F, + 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, + 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643, + 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF, + 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, + 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2 +} + +#elif _CODE_PAGE == 1257 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, + 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, + 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9 +}; + +#elif _CODE_PAGE == 1258 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */ + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, + 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF +}; + +#endif + + +#if !_TBLDEF || !_USE_LFN +#error This file is not needed in current configuration. Remove from the project. +#endif + + +WCHAR ff_convert ( /* Converted character, Returns zero on error */ + WCHAR src, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ +) +{ + WCHAR c; + + + if (src < 0x80) { /* ASCII */ + c = src; + + } else { + if (dir) { /* OEMCP to Unicode */ + c = (src >= 0x100) ? 0 : Tbl[src - 0x80]; + + } else { /* Unicode to OEMCP */ + for (c = 0; c < 0x80; c++) { + if (src == Tbl[c]) break; + } + c = (c + 0x80) & 0xFF; + } + } + + return c; +} + + +WCHAR ff_wtoupper ( /* Upper converted character */ + WCHAR chr /* Input character */ +) +{ + static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; + static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; + int i; + + + for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; + + return tbl_lower[i] ? tbl_upper[i] : chr; +} diff --git a/drivers/fatfs/diskio.h b/drivers/fatfs/diskio.h new file mode 100644 index 0000000..d4e7e00 --- /dev/null +++ b/drivers/fatfs/diskio.h @@ -0,0 +1,81 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO + +#define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + +DSTATUS disk_initialize (BYTE); +DSTATUS disk_status (BYTE); +DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); +#if _READONLY == 0 +DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); +#endif +DRESULT disk_ioctl (BYTE, BYTE, void*); +void disk_timerproc (void); + + + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + + +/* Command code for disk_ioctrl() */ + +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ +#define GET_SECTOR_SIZE 2 +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ +#define CTRL_POWER 4 +#define CTRL_LOCK 5 +#define CTRL_EJECT 6 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ +#define ATA_GET_REV 20 +#define ATA_GET_MODEL 21 +#define ATA_GET_SN 22 + + + +/* Card type flags (CardType) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + + +#define _DISKIO +#endif diff --git a/drivers/fatfs/ff.c b/drivers/fatfs/ff.c new file mode 100644 index 0000000..ad21b27 --- /dev/null +++ b/drivers/fatfs/ff.c @@ -0,0 +1,3154 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.07e (C)ChaN, 2009 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2009, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) patition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algolithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a plysical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSInfo support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close +/ without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same +/ or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a buffer configuration option. +/ Added long file name support. +/ Added multiple code page support. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size support. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended char. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. +/ Fixed name matching error on the 13 char boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper +/ case on non-LFN cfg. +/---------------------------------------------------------------------------*/ + +#include "projectconfig.h" +#include "ff.h" /* FatFs configurations and declarations */ +#include "diskio.h" /* Declarations of low level disk I/O functions */ + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 0x007E +#error Wrong include file (ff.h). +#endif + +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area must not be used in re-entrant configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } + +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res + +#endif + +#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } + +#ifndef NULL +#define NULL 0 +#endif + +/* Name status flags */ +#define NS 11 /* Offset of name status byte */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + + + +/*-------------------------------------------------------------------------- + + Private Work Area + +---------------------------------------------------------------------------*/ + +#if _DRIVES < 1 || _DRIVES > 9 +#error Number of drives must be 1-9. +#endif +static +FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */ + +static +WORD Fsid; /* File system mount ID */ + +#if _FS_RPATH +static +BYTE Drive; /* Current drive */ +#endif + + +#if _USE_LFN == 1 /* LFN with static LFN working buffer */ +static +WCHAR LfnBuf[_MAX_LFN + 1]; +#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR *lp = LfnBuf +#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp + +#elif _USE_LFN > 1 /* LFN with dynamic LFN working buffer */ +#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR lbuf[_MAX_LFN + 1], *lp = lbuf +#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp + +#else /* No LFN */ +#define NAMEBUF(sp,lp) BYTE sp[12] +#define INITBUF(dj,sp,lp) dj.fn = sp + +#endif + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, int cnt) { + char *d = (char*)dst; + const char *s = (const char *)src; + while (cnt--) *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, int cnt) { + char *d = (char*)dst; + while (cnt--) *d++ = (char)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, int cnt) { + const char *d = (const char *)dst, *s = (const char *)src; + int r = 0; + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT + +static +BOOL lock_fs ( + FATFS *fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS *fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Change window offset */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT move_window ( + FATFS *fs, /* File system object */ + DWORD sector /* Sector number to make apperance in the fs->win[] */ +) /* Move to zero only writes back dirty window */ +{ + DWORD wsect; + + + wsect = fs->winsect; + if (wsect != sector) { /* Changed current window */ +#if !_FS_READONLY + if (fs->wflag) { /* Write back dirty window if needed */ + if (disk_write(fs->drive, fs->win, wsect, 1) != RES_OK) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect < (fs->fatbase + fs->sects_fat)) { /* In FAT area */ + BYTE nf; + for (nf = fs->n_fats; nf > 1; nf--) { /* Refrect the change to all FAT copies */ + wsect += fs->sects_fat; + disk_write(fs->drive, fs->win, wsect, 1); + } + } + } +#endif + if (sector) { + if (disk_read(fs->drive, fs->win, sector, 1) != RES_OK) + return FR_DISK_ERR; + fs->winsect = sector; + } + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Clean-up cached data */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS *fs /* File system object */ +) +{ + FRESULT res; + + + res = move_window(fs, 0); + if (res == FR_OK) { + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { + fs->winsect = 0; + mem_set(fs->win, 0, 512); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + disk_write(fs->drive, fs->win, fs->fsi_sector, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drive, CTRL_SYNC, (void*)NULL) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + DWORD fsect; + + + if (clst < 2 || clst >= fs->max_clust) /* Range check */ + return 1; + + fsect = fs->fatbase; + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + if (move_window(fs, fsect + (bc / SS(fs)))) break; + wc = fs->win[bc & (SS(fs) - 1)]; bc++; + if (move_window(fs, fsect + (bc / SS(fs)))) break; + wc |= (WORD)fs->win[bc & (SS(fs) - 1)] << 8; + return (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fsect + (clst / (SS(fs) / 2)))) break; + return LD_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)]); + + case FS_FAT32 : + if (move_window(fs, fsect + (clst / (SS(fs) / 4)))) break; + return LD_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)]) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occured at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS *fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + DWORD fsect; + FRESULT res; + + + if (clst < 2 || clst >= fs->max_clust) { /* Range check */ + res = FR_INT_ERR; + + } else { + fsect = fs->fatbase; + switch (fs->fs_type) { + case FS_FAT12 : + bc = clst; bc += bc / 2; + res = move_window(fs, fsect + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc & (SS(fs) - 1)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fsect + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc & (SS(fs) - 1)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fsect + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + ST_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)], (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fsect + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + ST_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)], val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; + + + if (clst < 2 || clst >= fs->max_clust) { /* Check the range of cluster# */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->max_clust) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ + fs->free_clust++; + fs->fsi_flag = 1; + } + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl, mcl; + + + mcl = fs->max_clust; + if (clst == 0) { /* Create new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (scl == 0 || scl >= mcl) scl = 1; + } + else { /* Stretch existing chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < mcl) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= mcl) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free custer */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occured */ + return cs; + if (ncl == scl) return 0; /* No free custer */ + } + + if (put_fat(fs, ncl, 0x0FFFFFFF)) /* Mark the new cluster "in use" */ + return 0xFFFFFFFF; + if (clst != 0) { /* Link it to the previous one if needed */ + if (put_fat(fs, clst, ncl)) + return 0xFFFFFFFF; + } + + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag = 1; + } + + return ncl; /* Return new cluster number */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS *fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Seek directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_seek ( + DIR *dj, /* Pointer to directory object */ + WORD idx /* Directory index number */ +) +{ + DWORD clst; + WORD ic; + + + dj->index = idx; + clst = dj->sclust; + if (clst == 1 || clst >= dj->fs->max_clust) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dj->fs->dirbase; + + if (clst == 0) { /* Static table */ + dj->clust = clst; + if (idx >= dj->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32); /* Sector# */ + } + else { /* Dynamic table */ + ic = SS(dj->fs) / 32 * dj->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dj->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dj->fs->max_clust) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dj->clust = clst; + dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32); /* Sector# */ + } + + dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not streach */ + DIR *dj, /* Pointer to directory object */ + BOOL streach /* FALSE: Do not streach table, TRUE: Streach table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dj->index + 1; + if (!i || !dj->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dj->fs) / 32))) { /* Sector changed? */ + dj->sect++; /* Next sector */ + + if (dj->clust == 0) { /* Static table */ + if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dj->fs, dj->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dj->fs->max_clust) { /* When it reached end of dynamic table */ +#if !_FS_READONLY + BYTE c; + if (!streach) return FR_NO_FILE; /* When do not streach, report EOT */ + clst = create_chain(dj->fs, dj->clust); /* Streach cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up streached table */ + if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */ + mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */ + dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */ + for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */ + dj->fs->wflag = 1; + if (move_window(dj->fs, 0)) return FR_DISK_ERR; + dj->fs->winsect++; + } + dj->fs->winsect -= c; /* Rewind window address */ +#else + return FR_NO_FILE; /* Report EOT */ +#endif + } + dj->clust = clst; /* Initialize data for new cluster */ + dj->sect = clust2sect(dj->fs, clst); + } + } + } + + dj->index = i; + dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32; + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */ + + +static +BOOL cmp_lfn ( /* TRUE:Matched, FALSE:Not matched */ + WCHAR *lfnbuf, /* Pointer to the LFN to be compared */ + BYTE *dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return FALSE; /* Not matched */ + } else { + if (uc != 0xFFFF) return FALSE; /* Check filler */ + } + } while (++s < 13); /* Repeat until all chars in the entry are checked */ + + if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return FALSE; + + return TRUE; /* The part of LFN matched */ +} + + + +static +BOOL pick_lfn ( /* TRUE:Succeeded, FALSE:Buffer overflow */ + WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + int i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last char has not been processed */ + if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return FALSE; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return TRUE; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR *lfnbuf, /* Pointer to the LFN buffer */ + BYTE *dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + int i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding chars following last char */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE *dst, /* Pointer to genartated SFN */ + const BYTE *src, /* Pointer to source SFN to be modified */ + const WCHAR *lfn, /* Pointer to LFN */ + WORD num /* Sequense number */ +) +{ + char ns[8]; + int i, j; + + + mem_cpy(dst, src, 11); + + if (num > 5) { /* On many collisions, generate a hash number instead of sequencial number */ + do num = (num >> 1) + (num << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa */ + i = 7; + do { + ns[i--] = (num % 10) + '0'; + num /= 10; + } while (num); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE *dir /* Ptr to directory entry */ +) +{ + BYTE sum = 0; + int n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR *dj /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_seek(dj, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dj->lfn) { + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; /* LFN start order */ + dj->lfn_idx = dj->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +FRESULT dir_read ( + DIR *dj /* Pointer to the directory object that pointing the entry to be read */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dj->sect) { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + dir = dj->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & 0x40) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= 0xBF; ord = c; + dj->lfn_idx = dj->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dj->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dj, FALSE); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dj->sect = 0; + + return res; +} +#endif + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR *dj /* Target directory with object name to be created */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN /* LFN configuration */ + WORD n, ne, is; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dj->fn; lfn = dj->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */ + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dj->lfn = NULL; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dj); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dj->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve reserve an SFN + LFN entries. */ + for (ne = 0; lfn[ne]; ne++) ; + ne = (ne + 25) / 13; + } else { /* Otherwise reserve only an SFN entry. */ + ne = 1; + } + + /* Reserve contiguous entries */ + res = dir_seek(dj, 0); + if (res != FR_OK) return res; + n = is = 0; + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; /* Check the entry status */ + if (c == 0xE5 || c == 0) { /* Is it a blank entry? */ + if (n == 0) is = dj->index; /* First index of the contigulus entry */ + if (++n == ne) break; /* A contiguous entry that requiered count is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dj, TRUE); /* Next entry with table streach */ + } while (res == FR_OK); + + if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */ + res = dir_seek(dj, is); + if (res == FR_OK) { + sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */ + ne--; + do { /* Store LFN entries in bottom first */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum); + dj->fs->wflag = 1; + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK && --ne); + } + } + +#else /* Non LFN configuration */ + res = dir_seek(dj, 0); + if (res == FR_OK) { + do { /* Find a blank entry for the SFN */ + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + c = *dj->dir; + if (c == 0xE5 || c == 0) break; /* Is it a blank entry? */ + res = dir_next(dj, TRUE); /* Next entry with table streach */ + } while (res == FR_OK); + } +#endif + + if (res == FR_OK) { /* Initialize the SFN entry */ + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + dir = dj->dir; + mem_set(dir, 0, 32); /* Clean the entry */ + mem_cpy(dir, dj->fn, 11); /* Put SFN */ + dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */ + dj->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR *dj /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dj->index; /* SFN index */ + res = dir_seek(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dj->fs, dj->sect); + if (res != FR_OK) break; + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dj, FALSE); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_seek(dj, dj->index); + if (res == FR_OK) { + res = move_window(dj->fs, dj->sect); + if (res == FR_OK) { + *dj->dir = 0xE5; /* Mark the entry "deleted" */ + dj->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR *dj, /* Pointer to the directory object */ + const XCHAR **path /* Pointer to pointer to the segment in the path string */ +) +{ +#ifdef _EXCVT + static const BYTE cvt[] = _EXCVT; +#endif + +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + int i, ni, si, di; + const XCHAR *p; + + /* Create LFN in Unicode */ + si = di = 0; + p = *path; + lfn = dj->lfn; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* If it is a DBC 1st byte */ + b = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) /* Reject invalid code for DBC */ + return FR_INVALID_NAME; + w = (w << 8) + b; + } + w = ff_convert(w, 1); /* Convert OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode char */ + } + *path = &p[si]; /* Rerurn pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dj->fn[i] = (i < di) ? '.' : ' '; + dj->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di - 1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject null string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dj->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN char */ + if (!w) break; /* Break on enf of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII char */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = cvt[w - 0x80]; /* Convert extended char to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte char */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dj->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte char */ + if (!w || chk_chr("+,;[=]", w)) { /* Replace illegal chars for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dj->fn[i++] = (BYTE)w; + } + + if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dj->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + int ni, si, i; + const char *p; + + /* Create file name in directory form */ + sfn = dj->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; + p = *path; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Rerurn pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended char */ +#ifdef _EXCVT + c = cvt[c - 0x80]; /* Convert extend char (SBCS) */ +#else + b |= 3; /* Eliminate NT flag if ext char is exist */ +#if !_DF1S /* ASCII only cfg */ + return FR_INVALID_NAME; +#endif +#endif + } + if (IsDBCS1(c)) { /* DBC 1st byte? */ + d = p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr(" \"*+,[=]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Rerurn pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject null string */ + if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Filename has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 +static +void get_fileinfo ( /* No return code */ + DIR *dj, /* Pointer to the directory object */ + FILINFO *fno /* Pointer to the file information to be filled */ +) +{ + int i; + BYTE c, nt, *dir; + char *p; + + + p = fno->fname; + if (dj->sect) { + dir = dj->dir; + nt = dir[DIR_NTres]; /* NT flag */ + for (i = 0; i < 8; i++) { /* Copy name body */ + c = dir[i]; + if (c == ' ') break; + if (c == 0x05) c = 0xE5; + if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20; + *p++ = c; + } + if (dir[8] != ' ') { /* Copy name extension */ + *p++ = '.'; + for (i = 8; i < 11; i++) { + c = dir[i]; + if (c == ' ') break; + if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20; + *p++ = c; + } + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; + +#if _USE_LFN + if (fno->lfname) { + XCHAR *tp = fno->lfname; + WCHAR w, *lfn; + + i = 0; + if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */ + lfn = dj->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN char */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM conversion */ + if (!w) { i = 0; break; } /* Could not convert, no LFN */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */ + tp[i++] = (XCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */ + tp[i++] = (XCHAR)w; + } + } + tp[i] = 0; /* Terminator */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR *dj, /* Directory object to return last directory and found object */ + const XCHAR *path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, last; + + + while (!_USE_LFN && *path == ' ') path++; /* Skip leading spaces */ +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dj->sclust = 0; /* Strip it and start from the root dir */ + } else { /* No heading saparator */ + dj->sclust = dj->fs->cdir; /* Start from the current dir */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dj->sclust = 0; /* Start from the root dir */ +#endif + + if ((UINT)*path < ' ') { /* Null path means the start directory itself */ + res = dir_seek(dj, 0); + dj->dir = NULL; + + } else { /* Follow path */ + for (;;) { + res = create_name(dj, &path); /* Get a segment */ + if (res != FR_OK) break; + res = dir_find(dj); /* Find it */ + last = *(dj->fn+NS) & NS_LAST; + if (res != FR_OK) { /* Could not find the object */ + if (res == FR_NO_FILE && !last) + res = FR_NO_PATH; + break; + } + if (last) break; /* Last segment match. Function completed. */ + dir = dj->dir; /* There is next segment. Follow the sub directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ + res = FR_NO_PATH; break; + } + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load boot record and check if it is an FAT boot record */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */ + FATFS *fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK) /* Load boot record */ + return 3; + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Make sure that the file system is valid */ +/*-----------------------------------------------------------------------*/ + + +FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occured */ + const XCHAR **path, /* Pointer to pointer to the path name (drive number) */ + FATFS **rfs, /* Pointer to pointer to the found file system object */ + BYTE chk_wp /* !=0: Check media write protection for write access */ +) +{ + BYTE fmt, *tbl; + UINT vol; + DSTATUS stat; + DWORD bsect, fsize, tsect, mclst; + const XCHAR *p = *path; + FATFS *fs; + + /* Get logical drive number from the path name */ + vol = p[0] - '0'; /* Is there a drive number? */ + if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ + p += 2; *path = p; /* Return pointer to the path name */ + } else { /* No drive number is given */ +#if _FS_RPATH + vol = Drive; /* Use current drive */ +#else + vol = 0; /* Use drive 0 */ +#endif + } + + /* Check if the logical drive is valid or not */ + if (vol >= _DRIVES) /* Is the drive number valid? */ + return FR_INVALID_DRIVE; + *rfs = fs = FatFs[vol]; /* Returen pointer to the corresponding file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock file system */ + + if (fs->fs_type) { /* If the logical drive has been mounted */ + stat = disk_status(fs->drive); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + return FR_OK; /* The file system object is valid */ + } + } + + /* The logical drive must be mounted. Following code attempts to mount the volume */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drive = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drive); /* Initialize low level disk I/O layer */ + if (stat & STA_NOINIT) /* Check if the drive is ready */ + return FR_NOT_READY; +#if _MAX_SS != 512 /* Get disk sector size if needed */ + if (disk_ioctl(fs->drive, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_NO_FILESYSTEM; +#endif +#if !_FS_READONLY + if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#endif + /* Search FAT partition on the drive */ + fmt = check_fs(fs, bsect = 0); /* Check sector 0 as an SFD format */ + if (fmt == 1) { /* Not an FAT boot record, it may be patitioned */ + /* Check a partition listed in top of the partition table */ + tbl = &fs->win[MBR_Table + LD2PT(vol) * 16]; /* Partition table */ + if (tbl[4]) { /* Is the partition existing? */ + bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ + fmt = check_fs(fs, bsect); /* Check the partition */ + } + } + if (fmt == 3) return FR_DISK_ERR; + if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* No valid FAT patition is found */ + return FR_NO_FILESYSTEM; + + /* Initialize the file system object */ + fsize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fsize) fsize = LD_DWORD(fs->win+BPB_FATSz32); + fs->sects_fat = fsize; + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + fsize *= fs->n_fats; /* (Number of sectors in FAT area) */ + fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */ + fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Nmuber of root directory entries */ + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + fs->max_clust = mclst = (tsect /* Last cluster# + 1 (Number of clusters + 2) */ + - LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32) + ) / fs->csize + 2; + + fmt = FS_FAT12; /* Determine the FAT sub type */ + if (mclst >= 0xFF7) fmt = FS_FAT16; /* Number of clusters >= 0xFF5 */ + if (mclst >= 0xFFF7) fmt = FS_FAT32; /* Number of clusters >= 0xFFF5 */ + + if (fmt == FS_FAT32) + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + else + fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */ + fs->database = fs->fatbase + fsize + fs->n_rootdir / (SS(fs)/32); /* Data start sector (lba) */ + +#if !_FS_READONLY + /* Initialize allocation information */ + fs->free_clust = 0xFFFFFFFF; + fs->wflag = 0; + /* Get fsinfo if needed */ + if (fmt == FS_FAT32) { + fs->fsi_flag = 0; + fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); + if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK && + LD_WORD(fs->win+BS_55AA) == 0xAA55 && + LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && + LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->winsect = 0; /* Invalidate sector cache */ +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif + fs->id = ++Fsid; /* File system mount ID */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/dir object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + FATFS *fs, /* Pointer to the file system object */ + WORD id /* Member id of the target object to be checked */ +) +{ + if (!fs || !fs->fs_type || fs->id != id) + return FR_INVALID_OBJECT; + + ENTER_FF(fs); /* Lock file system */ + + if (disk_status(fs->drive) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Locical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + BYTE vol, /* Logical drive number to be mounted/unmounted */ + FATFS *fs /* Pointer to new file system object (NULL for unmount)*/ +) +{ + FATFS *rfs; + + + if (vol >= _DRIVES) /* Check if the drive number is valid */ + return FR_INVALID_DRIVE; + rfs = FatFs[vol]; /* Get current fs object */ + + if (rfs) { +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR; +#endif + rfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL *fp, /* Pointer to the blank file object */ + const XCHAR *path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + fp->fs = NULL; /* Clear file object */ +#if !_FS_READONLY + mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW); + res = chk_mounted(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW))); +#else + mode &= FA_READ; + res = chk_mounted(&path, &dj.fs, 0); +#endif + if (res != FR_OK) LEAVE_FF(dj.fs, res); + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + +#if !_FS_READONLY + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD ps, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ + res = dir_register(&dj); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + mode |= FA_CREATE_ALWAYS; + dir = dj.dir; /* Created entry (SFN entry) */ + } + else { /* Any object is already existing */ + if (mode & FA_CREATE_NEW) /* Cannot create new */ + LEAVE_FF(dj.fs, FR_EXIST); + dir = dj.dir; + if (!dir || (dir[DIR_Attr] & (AM_RDO | AM_DIR))) /* Cannot overwrite it (R/O or DIR) */ + LEAVE_FF(dj.fs, FR_DENIED); + if (mode & FA_CREATE_ALWAYS) { /* Resize it to zero on over write mode */ + cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); /* Get start cluster */ + ST_WORD(dir+DIR_FstClusHI, 0); /* cluster = 0 */ + ST_WORD(dir+DIR_FstClusLO, 0); + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + dj.fs->wflag = 1; + ps = dj.fs->winsect; /* Remove the cluster chain */ + if (cl) { + res = remove_chain(dj.fs, cl); + if (res) LEAVE_FF(dj.fs, res); + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + } + res = move_window(dj.fs, ps); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + } + } + if (mode & FA_CREATE_ALWAYS) { + dir[DIR_Attr] = 0; /* Reset attribute */ + ps = get_fattime(); + ST_DWORD(dir+DIR_CrtTime, ps); /* Created time */ + dj.fs->wflag = 1; + mode |= FA__WRITTEN; /* Set file changed flag */ + } + } + /* Open an existing file */ + else { +#endif /* !_FS_READONLY */ + if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */ + dir = dj.dir; + if (!dir || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */ + LEAVE_FF(dj.fs, FR_NO_FILE); +#if !_FS_READONLY + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + LEAVE_FF(dj.fs, FR_DENIED); + } + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dj.dir; +#endif + fp->flag = mode; /* File access mode */ + fp->org_clust = /* File start cluster */ + ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; fp->csect = 255; /* File pointer */ + fp->dsect = 0; + fp->fs = dj.fs; fp->id = dj.fs->id; /* Owner file system object of the file */ + + LEAVE_FF(dj.fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL *fp, /* Pointer to the file object */ + void *buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE *rbuff = buff; + + + *br = 0; /* Initialize bytes read */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data transferred */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector offset in the cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (fp->csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - fp->csect; + if (disk_read(fp->fs->drive, rbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) /* Replace one of the read sectors with cached data if it contains a dirty sector */ + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) /* Replace one of the read sectors with cached data if it contains a dirty sector */ + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + fp->csect += (BYTE)cc; /* Next sector address in the cluster */ + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + fp->csect++; /* Next sector address in the cluster */ + } + rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL *fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = buff; + + + *bw = 0; /* Initialize bytes written */ + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fsize + btw < fp->fsize) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data transferred */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->org_clust; /* Follow from the origin */ + if (clst == 0) /* When there is no cluster chain, */ + fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ + clst = create_chain(fp->fs, fp->curr_clust); /* Follow or streach cluster chain */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector address in the cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write back data buffer prior to following direct transfer */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write back data buffer prior to following direct transfer */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (fp->csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - fp->csect; + if (disk_write(fp->fs->drive, wbuff, sect, (BYTE)cc) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets dirty by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif + fp->csect += (BYTE)cc; /* Next sector address in the cluster */ + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly buffer filling at growing edge */ + if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector buffer with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + fp->csect++; /* Next sector address in the cluster */ + } + wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file changed flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tim; + BYTE *dir; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ +#if !_FS_TINY /* Write-back dirty buffer */ + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + ST_WORD(dir+DIR_FstClusLO, fp->org_clust); /* Update start cluster */ + ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16); + tim = get_fattime(); /* Updated time */ + ST_DWORD(dir+DIR_WrtTime, tim); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + + +#if _FS_READONLY + res = validate(fp->fs, fp->id); + if (res == FR_OK) fp->fs = NULL; + LEAVE_FF(fp->fs, res); +#else + res = f_sync(fp); + if (res == FR_OK) fp->fs = NULL; + return res; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Drive/Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH + +FRESULT f_chdrive ( + BYTE drv /* Drive number */ +) +{ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + + Drive = drv; + + return FR_OK; +} + + + + +FRESULT f_chdir ( + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + dir = dj.dir; /* Pointer to the entry */ + if (!dir) { + dj.fs->cdir = 0; /* No entry (root dir) */ + } else { + if (dir[DIR_Attr] & AM_DIR) /* Reached to the dir */ + dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + else + res = FR_NO_PATH; /* Could not reach the dir (it is a file) */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + +#endif + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL *fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + DWORD clst, bcs, nsect, ifptr; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; fp->csect = 255; + if (ofs > 0) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->curr_clust; + } else { /* When seek to back cluster, */ + clst = fp->org_clust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->org_clust = clst; + } +#endif + fp->curr_clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force streached if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->max_clust) ABORT(fp->fs, FR_INT_ERR); + fp->curr_clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + fp->csect = (BYTE)(ofs / SS(fp->fs)); /* Sector offset in the cluster */ + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += fp->csect; + fp->csect++; + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty buffer if needed */ + if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drive, fp->buf, nsect, 1) != RES_OK) + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set changed flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + + LEAVE_FF(fp->fs, res); +} + + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directroy Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR *dj, /* Pointer to directory object to create */ + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj->fs, 0); + if (res == FR_OK) { + INITBUF((*dj), sfn, lfn); + res = follow_path(dj, path); /* Follow the path to the directory */ + if (res == FR_OK) { /* Follow completed */ + dir = dj->dir; + if (dir) { /* It is not the root dir */ + if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ + dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + } else { /* The object is not a directory */ + res = FR_NO_PATH; + } + } + if (res == FR_OK) { + dj->id = dj->fs->id; + res = dir_seek(dj, 0); /* Rewind dir */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entry in Sequense */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR *dj, /* Pointer to the open directory object */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + NAMEBUF(sfn, lfn); + + + res = validate(dj->fs, dj->id); /* Check validity of the object */ + if (res == FR_OK) { + INITBUF((*dj), sfn, lfn); + if (!fno) { + res = dir_seek(dj, 0); + } else { + res = dir_read(dj); + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dj, fno); /* Get the object information */ + res = dir_next(dj, FALSE); /* Increment index for next */ + if (res == FR_NO_FILE) { + dj->sect = 0; + res = FR_OK; + } + } + } + } + + LEAVE_FF(dj->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const XCHAR *path, /* Pointer to the file path */ + FILINFO *fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + + + res = chk_mounted(&path, &dj.fs, 0); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follwo completed */ + if (dj.dir) /* Found an object */ + get_fileinfo(&dj, fno); + else /* It is root dir */ + res = FR_INVALID_NAME; + } + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const XCHAR *path, /* Pointer to the logical drive number (root dir) */ + DWORD *nclst, /* Pointer to the variable to return number of free clusters */ + FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ +) +{ + FRESULT res; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get drive number */ + res = chk_mounted(&path, fatfs, 0); + if (res != FR_OK) LEAVE_FF(*fatfs, res); + + /* If number of free cluster is valid, return it without cluster scan. */ + if ((*fatfs)->free_clust <= (*fatfs)->max_clust - 2) { + *nclst = (*fatfs)->free_clust; + LEAVE_FF(*fatfs, FR_OK); + } + + /* Get number of free clusters */ + fat = (*fatfs)->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(*fatfs, clst); + if (stat == 0xFFFFFFFF) LEAVE_FF(*fatfs, FR_DISK_ERR); + if (stat == 1) LEAVE_FF(*fatfs, FR_INT_ERR); + if (stat == 0) n++; + } while (++clst < (*fatfs)->max_clust); + } else { + clst = (*fatfs)->max_clust; + sect = (*fatfs)->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(*fatfs, sect++); + if (res != FR_OK) + LEAVE_FF(*fatfs, res); + p = (*fatfs)->win; + i = SS(*fatfs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + (*fatfs)->free_clust = n; + if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + *nclst = n; + + LEAVE_FF(*fatfs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL *fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check abort flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->org_clust); + fp->org_clust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->curr_clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->max_clust) { + res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } + } + if (res != FR_OK) fp->flag |= FA__ERROR; + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const XCHAR *path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + NAMEBUF(sfn, lfn); + BYTE *dir; + DWORD dclst; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */ + + dir = dj.dir; + if (!dir) /* Is it the root directory? */ + LEAVE_FF(dj.fs, FR_INVALID_NAME); + if (dir[DIR_Attr] & AM_RDO) /* Is it a R/O object? */ + LEAVE_FF(dj.fs, FR_DENIED); + dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO); + + if (dir[DIR_Attr] & AM_DIR) { /* It is a sub-directory */ + if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR); + mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + sdj.sclust = dclst; + res = dir_seek(&sdj, 2); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + res = dir_read(&sdj); + if (res == FR_OK) res = FR_DENIED; /* Not empty sub-dir */ + if (res != FR_NO_FILE) LEAVE_FF(dj.fs, res); + } + + res = dir_remove(&dj); /* Remove directory entry */ + if (res == FR_OK) { + if (dclst) + res = remove_chain(dj.fs, dclst); /* Remove the cluster chain */ + if (res == FR_OK) res = sync(dj.fs); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const XCHAR *path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir, n; + DWORD dsect, dclst, pclst, tim; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any file or directory is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res != FR_NO_FILE) /* Any error occured */ + LEAVE_FF(dj.fs, res); + + dclst = create_chain(dj.fs, 0); /* Allocate a new cluster for new directory table */ + res = FR_OK; + if (dclst == 0) res = FR_DENIED; + if (dclst == 1) res = FR_INT_ERR; + if (dclst == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) + res = move_window(dj.fs, 0); + if (res != FR_OK) LEAVE_FF(dj.fs, res); + dsect = clust2sect(dj.fs, dclst); + + dir = dj.fs->win; /* Initialize the new directory table */ + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + tim = get_fattime(); + ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_FstClusLO, dclst); + ST_WORD(dir+DIR_FstClusHI, dclst >> 16); + mem_cpy(dir+32, dir, 32); /* Create ".." entry */ + dir[33] = '.'; + pclst = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pclst == dj.fs->dirbase) + pclst = 0; + ST_WORD(dir+32+DIR_FstClusLO, pclst); + ST_WORD(dir+32+DIR_FstClusHI, pclst >> 16); + for (n = 0; n < dj.fs->csize; n++) { /* Write dot entries and clear left sectors */ + dj.fs->winsect = dsect++; + dj.fs->wflag = 1; + res = move_window(dj.fs, 0); + if (res) LEAVE_FF(dj.fs, res); + mem_set(dir, 0, SS(dj.fs)); + } + + res = dir_register(&dj); + if (res != FR_OK) { + remove_chain(dj.fs, dclst); + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tim); /* Crated time */ + ST_WORD(dir+DIR_FstClusLO, dclst); /* Table start cluster */ + ST_WORD(dir+DIR_FstClusHI, dclst >> 16); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change File Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const XCHAR *path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const XCHAR *path, /* Pointer to the file/directory name */ + const FILINFO *fno /* Pointer to the timestamp to be set */ +) +{ + FRESULT res; + DIR dj; + NAMEBUF(sfn, lfn); + BYTE *dir; + + + res = chk_mounted(&path, &dj.fs, 1); + if (res == FR_OK) { + INITBUF(dj, sfn, lfn); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const XCHAR *path_old, /* Pointer to the old name */ + const XCHAR *path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR dj_old, dj_new; + NAMEBUF(sfn, lfn); + BYTE buf[21], *dir; + DWORD dw; + + + INITBUF(dj_old, sfn, lfn); + res = chk_mounted(&path_old, &dj_old.fs, 1); + if (res == FR_OK) { + dj_new.fs = dj_old.fs; + res = follow_path(&dj_old, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (dj_old.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + } + if (res != FR_OK) LEAVE_FF(dj_old.fs, res); /* The old object is not found */ + + if (!dj_old.dir) LEAVE_FF(dj_old.fs, FR_NO_FILE); /* Is root dir? */ + mem_cpy(buf, dj_old.dir+DIR_Attr, 21); /* Save the object information */ + + mem_cpy(&dj_new, &dj_old, sizeof(DIR)); + res = follow_path(&dj_new, path_new); /* Check new object */ + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ + res = dir_register(&dj_new); /* Register the new object */ + if (res == FR_OK) { + dir = dj_new.dir; /* Copy object information into new entry */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + dj_old.fs->wflag = 1; + if (dir[DIR_Attr] & AM_DIR) { /* Update .. entry in the directory if needed */ + dw = clust2sect(dj_new.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(dj_new.fs, dw); + dir = dj_new.fs->win+32; + if (res == FR_OK && dir[1] == '.') { + dw = (dj_new.fs->fs_type == FS_FAT32 && dj_new.sclust == dj_new.fs->dirbase) ? 0 : dj_new.sclust; + ST_WORD(dir+DIR_FstClusLO, dw); + ST_WORD(dir+DIR_FstClusHI, dw >> 16); + dj_new.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj_old); /* Remove old entry */ + if (res == FR_OK) + res = sync(dj_old.fs); + } + } + } + + LEAVE_FF(dj_old.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (Available on only _FS_TINY cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL *fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btr, /* Number of bytes to forward */ + UINT *bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + + + *bf = 0; + + res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->flag & FA__ERROR) /* Check error flag */ + LEAVE_FF(fp->fs, FR_INT_ERR); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr && (*func)(NULL, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (fp->csect >= fp->fs->csize) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->org_clust : get_fat(fp->fs, fp->curr_clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->curr_clust = clst; /* Update current cluster */ + fp->csect = 0; /* Reset sector address in the cluster */ + } + fp->csect++; /* Next sector address in the cluster */ + } + sect = clust2sect(fp->fs, fp->curr_clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += fp->csect - 1; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btr) rcnt = btr; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Multiple of 32 and <= 2048 */ +#define N_FATS 1 /* 1 or 2 */ +#define MAX_SECTOR 131072000UL /* Maximum partition size */ +#define MIN_SECTOR 2000UL /* Minimum partition size */ + + +FRESULT f_mkfs ( + BYTE drv, /* Logical drive number */ + BYTE partition, /* Partitioning rule 0:FDISK, 1:SFD */ + WORD allocsize /* Allocation unit size [bytes] */ +) +{ + static const DWORD sstbl[] = { 2048000, 1024000, 512000, 256000, 128000, 64000, 32000, 16000, 8000, 4000, 0 }; + static const WORD cstbl[] = { 32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512 }; + BYTE fmt, m, *tbl; + DWORD b_part, b_fat, b_dir, b_data; /* Area offset (LBA) */ + DWORD n_part, n_rsv, n_fat, n_dir; /* Area size */ + DWORD n_clst, d, n; + WORD as; + FATFS *fs; + DSTATUS stat; + + + /* Check validity of the parameters */ + if (drv >= _DRIVES) return FR_INVALID_DRIVE; + if (partition >= 2) return FR_MKFS_ABORTED; + + /* Check mounted drive and clear work area */ + fs = FatFs[drv]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + drv = LD2PD(drv); + + /* Get disk statics */ + stat = disk_initialize(drv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK + || SS(fs) > _MAX_SS) + return FR_MKFS_ABORTED; +#endif + if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR) + return FR_MKFS_ABORTED; + if (n_part > MAX_SECTOR) n_part = MAX_SECTOR; + b_part = (!partition) ? 63 : 0; /* Boot sector */ + n_part -= b_part; + for (d = 512; d <= 32768U && d != allocsize; d <<= 1) ; /* Check validity of the allocation unit size */ + if (d != allocsize) allocsize = 0; + if (!allocsize) { /* Auto selection of cluster size */ + d = n_part; + for (as = SS(fs); as > 512U; as >>= 1) d >>= 1; + for (n = 0; d < sstbl[n]; n++) ; + allocsize = cstbl[n]; + } + if (allocsize < SS(fs)) allocsize = SS(fs); + + allocsize /= SS(fs); /* Number of sectors per cluster */ + + /* Pre-compute number of clusters and FAT type */ + n_clst = n_part / allocsize; + fmt = FS_FAT12; + if (n_clst >= 0xFF5) fmt = FS_FAT16; + if (n_clst >= 0xFFF5) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + switch (fmt) { + case FS_FAT12: + n_fat = ((n_clst * 3 + 1) / 2 + 3 + SS(fs) - 1) / SS(fs); + n_rsv = 1 + partition; + n_dir = N_ROOTDIR * 32 / SS(fs); + break; + case FS_FAT16: + n_fat = ((n_clst * 2) + 4 + SS(fs) - 1) / SS(fs); + n_rsv = 1 + partition; + n_dir = N_ROOTDIR * 32 / SS(fs); + break; + default: + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 33 - partition; + n_dir = 0; + } + b_fat = b_part + n_rsv; /* FATs start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory start sector */ + b_data = b_dir + n_dir; /* Data start sector */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); + n_fat += (n - b_data) / N_FATS; + /* b_dir and b_data are no longer used below */ + + /* Determine number of cluster and final check of validity of the FAT type */ + n_clst = (n_part - n_rsv - n_fat * N_FATS - n_dir) / allocsize; + if ( (fmt == FS_FAT16 && n_clst < 0xFF5) + || (fmt == FS_FAT32 && n_clst < 0xFFF5)) + return FR_MKFS_ABORTED; + + /* Create partition table if needed */ + if (!partition) { + DWORD n_disk = b_part + n_part; + + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; + ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */ + if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */ + n_disk = n_disk / 63 / 255; + tbl[7] = (BYTE)n_disk; + tbl[6] = (BYTE)((n_disk >> 2) | 63); + } else { + ST_WORD(&tbl[6], 0xFFFF); + } + tbl[5] = 254; + if (fmt != FS_FAT32) /* System ID */ + tbl[4] = (n_part < 0x10000) ? 0x04 : 0x06; + else + tbl[4] = 0x0c; + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_part); /* Partition size in LBA */ + ST_WORD(tbl+64, 0xAA55); /* Signature */ + if (disk_write(drv, fs->win, 0, 1) != RES_OK) + return FR_DISK_ERR; + partition = 0xF8; + } else { + partition = 0xF0; + } + + /* Create boot record */ + tbl = fs->win; /* Clear buffer */ + mem_set(tbl, 0, SS(fs)); + ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB); /* Boot code (jmp $, nop) */ + ST_WORD(tbl+BPB_BytsPerSec, SS(fs)); /* Sector size */ + tbl[BPB_SecPerClus] = (BYTE)allocsize; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + ST_WORD(tbl+BPB_RootEntCnt, SS(fs) / 32 * n_dir); /* Number of rootdir entries */ + if (n_part < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_part); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_part); + } + tbl[BPB_Media] = partition; /* Media descripter */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_part); /* Hidden sectors */ + n = get_fattime(); /* Use current time as a VSN */ + if (fmt != FS_FAT32) { + ST_DWORD(tbl+BS_VolID, n); /* Volume serial number */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of secters per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume lavel, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID32, n); /* Volume serial number */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of secters per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (bs+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (bs+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume lavel, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature */ + if (SS(fs) > 512U) { + ST_WORD(tbl+SS(fs)-2, 0xAA55); + } + if (disk_write(drv, tbl, b_part+0, 1) != RES_OK) + return FR_DISK_ERR; + if (fmt == FS_FAT32) + disk_write(drv, tbl, b_part+6, 1); + + /* Initialize FAT area */ + for (m = 0; m < N_FATS; m++) { + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + if (fmt != FS_FAT32) { + n = (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + n |= partition; + ST_DWORD(tbl, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + ST_DWORD(tbl+0, 0xFFFFFFF8); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0xFFFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */ + } + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Following FAT entries are filled by zero */ + for (n = 1; n < n_fat; n++) { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } + } + + /* Initialize Root directory */ + m = (BYTE)((fmt == FS_FAT32) ? allocsize : n_dir); + do { + if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) + return FR_DISK_ERR; + } while (--m); + + /* Create FSInfo record if needed */ + if (fmt == FS_FAT32) { + ST_WORD(tbl+BS_55AA, 0xAA55); + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); + ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF); + disk_write(drv, tbl, b_part+1, 1); + disk_write(drv, tbl, b_part+7, 1); + } + + return (disk_ioctl(drv, CTRL_SYNC, (void*)NULL) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ +char* f_gets ( + char* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer */ + FIL* fil /* Pointer to the file object */ +) +{ + int i = 0; + char *p = buff; + UINT rc; + + + while (i < len - 1) { /* Read bytes until buffer gets filled */ + f_read(fil, p, 1, &rc); + if (rc != 1) break; /* Break when no data to read */ +#if _USE_STRFUNC >= 2 + if (*p == '\r') continue; /* Strip '\r' */ +#endif + i++; + if (*p++ == '\n') break; /* Break when reached end of line */ + } + *p = 0; + return i ? buff : NULL; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ +int f_putc ( + int chr, /* A character to be output */ + FIL* fil /* Ponter to the file object */ +) +{ + UINT bw; + char c; + + +#if _USE_STRFUNC >= 2 + if (chr == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */ +#endif + if (!fil) { /* Special value may be used to switch the destination to any other device */ + /* put_console(chr); */ + return chr; + } + c = (char)chr; + f_write(fil, &c, 1, &bw); /* Write a byte to the file */ + return bw ? chr : EOF; /* Return the result */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ +int f_puts ( + const char* str, /* Pointer to the string to be output */ + FIL* fil /* Pointer to the file object */ +) +{ + int n; + + + for (n = 0; *str; str++, n++) { + if (f_putc(*str, fil) == EOF) return EOF; + } + return n; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ +int f_printf ( + FIL* fil, /* Pointer to the file object */ + const char* str, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + UCHAR c, f, r; + ULONG val; + char s[16]; + int i, w, res, cc; + + + va_start(arp, str); + + for (cc = res = 0; cc != EOF; res += cc) { + c = *str++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape cahracter */ + cc = f_putc(c, fil); + if (cc != EOF) cc = 1; + continue; + } + w = f = 0; + c = *str++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *str++; + } + while (c >= '0' && c <= '9') { /* Precision */ + w = w * 10 + (c - '0'); + c = *str++; + } + if (c == 'l') { /* Prefix: Size is long int */ + f |= 2; c = *str++; + } + if (c == 's') { /* Type is string */ + cc = f_puts(va_arg(arp, char*), fil); + continue; + } + if (c == 'c') { /* Type is character */ + cc = f_putc(va_arg(arp, int), fil); + if (cc != EOF) cc = 1; + continue; + } + r = 0; + if (c == 'd') r = 10; /* Type is signed decimal */ + if (c == 'u') r = 10; /* Type is unsigned decimal */ + if (c == 'X') r = 16; /* Type is unsigned hexdecimal */ + if (r == 0) break; /* Unknown type */ + if (f & 2) { /* Get the value */ + val = (ULONG)va_arg(arp, long); + } else { + val = (c == 'd') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int); + } + /* Put numeral string */ + if (c == 'd') { + if (val & 0x80000000) { + val = 0 - val; + f |= 4; + } + } + i = sizeof(s) - 1; s[i] = 0; + do { + c = (UCHAR)(val % r + '0'); + if (c > '9') c += 7; + s[--i] = c; + val /= r; + } while (i && val); + if (i && (f & 4)) s[--i] = '-'; + w = sizeof(s) - 1 - w; + while (i && i > w) s[--i] = (f & 1) ? '0' : ' '; + cc = f_puts(&s[i], fil); + } + + va_end(arp); + return (cc == EOF) ? cc : res; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/drivers/fatfs/ff.h b/drivers/fatfs/ff.h new file mode 100644 index 0000000..090f405 --- /dev/null +++ b/drivers/fatfs/ff.h @@ -0,0 +1,596 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.07e (C)ChaN, 2009 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following trems. +/ +/ Copyright (C) 2009, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 0x007E + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONFIG +#error Wrong configuration file (ffconf.h). +#endif + + +/* DBCS code ranges and SBCS extend char conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + + +/* Character code support macros */ + +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) + +#if _DF1S /* DBCS configuration */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* SBCS configuration */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + + +/* Definitions corresponds to multi partition */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ + +typedef struct _PARTITION { + BYTE pd; /* Physical drive# */ + BYTE pt; /* Partition # (0-3) */ +} PARTITION; + +extern +const PARTITION Drives[]; /* Logical drive# to physical location conversion table */ +#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */ +#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */ + +#else /* Single partition configuration */ + +#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */ +#define LD2PT(drv) 0 /* Always mounts the 1st partition */ + +#endif + + + +/* Definitions corresponds to multiple sector size */ + +#if _MAX_SS == 512 /* Single sector size */ +#define SS(fs) 512U + +#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */ +#define SS(fs) ((fs)->s_size) + +#else +#error Sector size must be 512, 1024, 2048 or 4096. + +#endif + + + +/* Type of file name on FatFs API */ + +#if _LFN_UNICODE && _USE_LFN +typedef WCHAR XCHAR; /* Unicode */ +#else +typedef char XCHAR; /* SBCS, DBCS */ +#endif + + + +/* File system object structure */ + +typedef struct _FATFS_ { + BYTE fs_type; /* FAT sub type */ + BYTE drive; /* Physical drive number */ + BYTE csize; /* Number of sectors per cluster */ + BYTE n_fats; /* Number of FAT copies */ + BYTE wflag; /* win[] dirty flag (1:must be written back) */ + BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */ +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if _MAX_SS != 512 + WORD s_size; /* Sector size */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ + DWORD fsi_sector; /* fsinfo sector */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory (0:root)*/ +#endif + DWORD sects_fat; /* Sectors per fat */ + DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */ +} FATFS; + + + +/* Directory object structure */ + +typedef struct _DIR_ { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Static table) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File object structure */ + +typedef struct _FIL_ { + FATFS* fs; /* Pointer to the owner file system object */ + WORD id; /* Owner file system mount ID */ + BYTE flag; /* File status flags */ + BYTE csect; /* Sector address in the cluster */ + DWORD fptr; /* File R/W pointer */ + DWORD fsize; /* File size */ + DWORD org_clust; /* File start cluster */ + DWORD curr_clust; /* Current cluster */ + DWORD dsect; /* Current data sector */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Ponter to the directory entry in the window */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS];/* File R/W buffer */ +#endif +} FIL; + + + +/* File status structure */ + +typedef struct _FILINFO_ { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + char fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + XCHAR* lfname; /* Pointer to the LFN buffer */ + int lfsize; /* Size of LFN buffer [chrs] */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* 0 */ + FR_DISK_ERR, /* 1 */ + FR_INT_ERR, /* 2 */ + FR_NOT_READY, /* 3 */ + FR_NO_FILE, /* 4 */ + FR_NO_PATH, /* 5 */ + FR_INVALID_NAME, /* 6 */ + FR_DENIED, /* 7 */ + FR_EXIST, /* 8 */ + FR_INVALID_OBJECT, /* 9 */ + FR_WRITE_PROTECTED, /* 10 */ + FR_INVALID_DRIVE, /* 11 */ + FR_NOT_ENABLED, /* 12 */ + FR_NO_FILESYSTEM, /* 13 */ + FR_MKFS_ABORTED, /* 14 */ + FR_TIMEOUT /* 15 */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ +FRESULT f_open (FIL*, const XCHAR*, BYTE); /* Open or create a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ +FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ +FRESULT f_close (FIL*); /* Close an open file object */ +FRESULT f_opendir (DIR*, const XCHAR*); /* Open an existing directory */ +FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ +FRESULT f_stat (const XCHAR*, FILINFO*); /* Get file status */ +FRESULT f_getfree (const XCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ +FRESULT f_truncate (FIL*); /* Truncate file */ +FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ +FRESULT f_unlink (const XCHAR*); /* Delete an existing file or directory */ +FRESULT f_mkdir (const XCHAR*); /* Create a new directory */ +FRESULT f_chmod (const XCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ +FRESULT f_utime (const XCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_rename (const XCHAR*, const XCHAR*); /* Rename/Move a file or directory */ +FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ +FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */ +FRESULT f_chdir (const XCHAR*); /* Change current directory */ +FRESULT f_chdrive (BYTE); /* Change current drive */ + +#if _USE_STRFUNC +int f_putc (int, FIL*); /* Put a character to the file */ +int f_puts (const char*, FIL*); /* Put a string to the file */ +int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */ +char* f_gets (char*, int, FIL*); /* Get a string from the file */ +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) +#ifndef EOF +#define EOF -1 +#endif +#endif + + + +/*--------------------------------------------------------------*/ +/* User defined functions */ + +/* Real time clock */ +#if !_FS_READONLY +DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */ + /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */ +#endif + +/* Unicode - OEM code conversion */ +#if _USE_LFN +WCHAR ff_convert (WCHAR, UINT); +WCHAR ff_wtoupper (WCHAR); +#endif + +/* Sync functions */ +#if _FS_REENTRANT +BOOL ff_cre_syncobj(BYTE, _SYNC_t*); +BOOL ff_del_syncobj(_SYNC_t); +BOOL ff_req_grant(_SYNC_t); +void ff_rel_grant(_SYNC_t); +#endif + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 +#if _FS_READONLY == 0 +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif +#define FA__ERROR 0x80 + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* FatFs refers the members in the FAT structures with byte offset instead +/ of structure member because there are incompatibility of the packing option +/ between various compilers. */ + +#define BS_jmpBoot 0 +#define BS_OEMName 3 +#define BPB_BytsPerSec 11 +#define BPB_SecPerClus 13 +#define BPB_RsvdSecCnt 14 +#define BPB_NumFATs 16 +#define BPB_RootEntCnt 17 +#define BPB_TotSec16 19 +#define BPB_Media 21 +#define BPB_FATSz16 22 +#define BPB_SecPerTrk 24 +#define BPB_NumHeads 26 +#define BPB_HiddSec 28 +#define BPB_TotSec32 32 +#define BS_55AA 510 + +#define BS_DrvNum 36 +#define BS_BootSig 38 +#define BS_VolID 39 +#define BS_VolLab 43 +#define BS_FilSysType 54 + +#define BPB_FATSz32 36 +#define BPB_ExtFlags 40 +#define BPB_FSVer 42 +#define BPB_RootClus 44 +#define BPB_FSInfo 48 +#define BPB_BkBootSec 50 +#define BS_DrvNum32 64 +#define BS_BootSig32 66 +#define BS_VolID32 67 +#define BS_VolLab32 71 +#define BS_FilSysType32 82 + +#define FSI_LeadSig 0 +#define FSI_StrucSig 484 +#define FSI_Free_Count 488 +#define FSI_Nxt_Free 492 + +#define MBR_Table 446 + +#define DIR_Name 0 +#define DIR_Attr 11 +#define DIR_NTres 12 +#define DIR_CrtTime 14 +#define DIR_CrtDate 16 +#define DIR_FstClusHI 20 +#define DIR_WrtTime 22 +#define DIR_WrtDate 24 +#define DIR_FstClusLO 26 +#define DIR_FileSize 28 +#define LDIR_Ord 0 +#define LDIR_Attr 11 +#define LDIR_Type 12 +#define LDIR_Chksum 13 +#define LDIR_FstClusLO 26 + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + + +#endif /* _FATFS */ diff --git a/drivers/fatfs/ffconf.h b/drivers/fatfs/ffconf.h new file mode 100644 index 0000000..3453ad1 --- /dev/null +++ b/drivers/fatfs/ffconf.h @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.07e (C)ChaN, 2009 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONFIG +#define _FFCONFIG 0x007E + +#include "projectconfig.h" + +/*---------------------------------------------------------------------------/ +/ Function and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 1 /* 0 or 1 */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY CFG_SDCARD_READONLY // 0 /* 0 or 1 */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, +/ f_truncate and useless f_getfree. */ + + +#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove some functions. +/ +/ 0: Full function. +/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename +/ are removed. +/ 2: f_opendir and f_readdir are removed in addition to level 1. +/ 3: f_lseek is removed in addition to level 2. */ + + +#define _USE_STRFUNC 0 /* 0, 1 or 2 */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0 or 1 */ +/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FORWARD 0 /* 0 or 1 */ +/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 858 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII only (Valid for non LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0, 1 or 2 */ +#define _MAX_LFN 64 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN support. +/ +/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. +/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN, +/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added +/ to the project. */ + + +#define _LFN_UNICODE 0 /* 0 or 1 */ +/* To switch the character code set on FatFs API to Unicode, +/ enable LFN feature and set _LFN_UNICODE to 1. +*/ + + +#define _FS_RPATH 0 /* 0 or 1 */ +/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, +/ f_chdrive function are available. +/ Note that output of the f_readdir fnction is affected by this option. */ + + + +/*---------------------------------------------------------------------------/ +/ Physical Drive Configurations +/----------------------------------------------------------------------------*/ + +#define _DRIVES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for floppy disk (512/1024) and optical disk (512/2048). +/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted +/ to the disk_ioctl function. */ + + +#define _MULTI_PARTITION 0 /* 0 or 1 */ +/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical +/ drive number and can mount only first primaly partition. When it is set to 1, +/ each volume is tied to the partitions listed in Drives[]. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* The _WORD_ACCESS option defines which access method is used to the word +/ data on the FAT volume. +/ +/ 0: Byte-by-byte access. Always compatible with all platforms. +/ 1: Word access. Do not choose this unless following condition is met. +/ +/ When the byte order on the memory is big-endian or address miss-aligned +/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0. +/ If it is not the case, the value can also be set to 1 to improve the +/ performance and code size. */ + + +#define _FS_REENTRANT 0 /* 0 or 1 */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +/* The _FS_REENTRANT option switches the reentrancy of the FatFs module. +/ +/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable reentrancy. Also user provided synchronization handlers, +/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj +/ function must be added to the project. */ + + +#endif /* _FFCONFIG */ diff --git a/drivers/fatfs/integer.h b/drivers/fatfs/integer.h new file mode 100644 index 0000000..ee3bfa2 --- /dev/null +++ b/drivers/fatfs/integer.h @@ -0,0 +1,34 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER + +#if 0 +#include +#else + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef signed char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#define _INTEGER +#endif diff --git a/drivers/fatfs/mmc.c b/drivers/fatfs/mmc.c new file mode 100644 index 0000000..6e01bb1 --- /dev/null +++ b/drivers/fatfs/mmc.c @@ -0,0 +1,684 @@ +/*-----------------------------------------------------------------------*/ +/* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */ +/* are platform dependent. */ +/*-----------------------------------------------------------------------*/ + + +#include "projectconfig.h" +#include "diskio.h" +#include "core/gpio/gpio.h" +#include "core/ssp/ssp.h" +#include "core/systick/systick.h" + + +/* Definitions for MMC/SDC command */ +#define CMD0 (0x40+0) /* GO_IDLE_STATE */ +#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */ +#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */ +#define CMD8 (0x40+8) /* SEND_IF_COND */ +#define CMD9 (0x40+9) /* SEND_CSD */ +#define CMD10 (0x40+10) /* SEND_CID */ +#define CMD12 (0x40+12) /* STOP_TRANSMISSION */ +#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */ +#define CMD16 (0x40+16) /* SET_BLOCKLEN */ +#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */ +#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */ +#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */ +#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */ +#define CMD24 (0x40+24) /* WRITE_BLOCK */ +#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */ +#define CMD55 (0x40+55) /* APP_CMD */ +#define CMD58 (0x40+58) /* READ_OCR */ + + +/* Port Controls (Platform dependent) */ +#define CS_LOW() gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 0) +#define CS_HIGH() gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1) + +// #define FCLK_SLOW() /* Set slow clock (100k-400k) */ +// #define FCLK_FAST() /* Set fast clock (depends on the CSD) */ + +#define FDELAY(ms) systickDelay(ms) // Assumes delay = 1ms, ugly + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + +static volatile +DSTATUS Stat = STA_NOINIT; /* Disk status */ + +static volatile +BYTE Timer1, Timer2; /* 100Hz decrement timer */ + +static +BYTE CardType; /* Card type flags */ + +/**************************************************************************/ +/*! + Set SSP clock to slow (400 KHz) +*/ +/**************************************************************************/ +static void FCLK_SLOW() +{ + /* Divide by 10 (SSPCLKDIV also enables to SSP CLK) */ + SCB_SSP0CLKDIV = SCB_SSP0CLKDIV_DIV10; + + /* (PCLK / (CPSDVSR * [SCR+1])) = (7,200,000 / (2 x [8 + 1])) = 400 KHz */ + uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit + | SSP_SSP0CR0_FRF_SPI // Frame format = SPI + | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 + + // Set clock polarity (low between frames) + // configReg &= ~SSP_SSP0CR0_CPOL_MASK; + // configReg |= SSP_SSP0CR0_CPOL_LOW; + + // Set edge transition (leading edge) + // configReg &= ~SSP_SSP0CR0_CPHA_MASK; + // configReg |= SSP_SSP0CR0_CPHA_FIRST; + + // Assign config values to SSP0CR0 + SSP_SSP0CR0 = configReg; + + /* Clock prescale register must be even and at least 2 in master mode */ + SSP_SSP0CPSR = SSP_SSP0CPSR_CPSDVSR_DIV2; +} + +/**************************************************************************/ +/*! + Set SSP clock to fast (6.0 MHz) +*/ +/**************************************************************************/ +static void FCLK_FAST() +{ + /* Divide by 1 (SSPCLKDIV also enables to SSP CLK) */ + SCB_SSP0CLKDIV = SCB_SSP0CLKDIV_DIV1; + + /* (PCLK / (CPSDVSR * [SCR+1])) = (72,000,000 / (2 * [5 + 1])) = 6.0 MHz */ + uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit + | SSP_SSP0CR0_FRF_SPI // Frame format = SPI + | SSP_SSP0CR0_SCR_5); // Serial clock rate = 5 + + // Set clock polarity (low between frames) + // configReg &= ~SSP_SSP0CR0_CPOL_MASK; + // configReg |= SSP_SSP0CR0_CPOL_LOW; + + // Set edge transition (leading edge) + // configReg &= ~SSP_SSP0CR0_CPHA_MASK; + // configReg |= SSP_SSP0CR0_CPHA_FIRST; + + // Assign config values to SSP0CR0 + SSP_SSP0CR0 = configReg; + + /* Clock prescale register must be even and at least 2 in master mode */ + SSP_SSP0CPSR = SSP_SSP0CPSR_CPSDVSR_DIV2; +} + +/*-----------------------------------------------------------------------*/ +/* Transmit a byte to MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +//#define xmit_spi(dat) (SSPSend((uint8_t*)&(dat), 1)) +static void xmit_spi(BYTE dat) +{ + sspSend(0, (uint8_t*) &dat, 1); +} + + +/*-----------------------------------------------------------------------*/ +/* Receive a byte from MMC via SPI (Platform dependent) */ +/*-----------------------------------------------------------------------*/ + +static +BYTE rcvr_spi (void) +{ + BYTE data = 0; + + sspReceive(0, &data, 1); + + return data; +} + +/* Alternative macro to receive data fast */ + +#define rcvr_spi_m(dst) \ + do { \ + sspReceive(0, (uint8_t*)(dst), 1); \ + } while(0) + + + + +/*-----------------------------------------------------------------------*/ +/* Wait for card ready */ +/*-----------------------------------------------------------------------*/ + +static +BYTE wait_ready (void) +{ + BYTE res; + + + Timer2 = 50; /* Wait for ready in timeout of 500ms */ + rcvr_spi(); + do + res = rcvr_spi(); + while ((res != 0xFF) && Timer2); + + return res; +} + + + +/*-----------------------------------------------------------------------*/ +/* Deselect the card and release SPI bus */ +/*-----------------------------------------------------------------------*/ + +static +void deselect (void) +{ + CS_HIGH(); + rcvr_spi(); +} + + + +/*-----------------------------------------------------------------------*/ +/* Select the card and wait ready */ +/*-----------------------------------------------------------------------*/ + +static +BOOL select (void) /* TRUE:Successful, FALSE:Timeout */ +{ + CS_LOW(); + if (wait_ready() != 0xFF) { + deselect(); + return FALSE; + } + return TRUE; +} + + + +/*-----------------------------------------------------------------------*/ +/* Power Control (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* When the target system does not support socket power control, there */ +/* is nothing to do in these functions and chk_power always returns 1. */ + +static +void power_on (void) +{ +} + +static +void power_off (void) +{ +} + +static +int chk_power(void) /* Socket power state: 0=off, 1=on */ +{ + return 1; +} + + + +/*-----------------------------------------------------------------------*/ +/* Receive a data packet from MMC */ +/*-----------------------------------------------------------------------*/ + +static +BOOL rcvr_datablock ( + BYTE *buff, /* Data buffer to store received data */ + UINT btr /* Byte count (must be multiple of 4) */ +) +{ + BYTE token; + + + Timer1 = 20; + do { /* Wait for data packet in timeout of 200ms */ + token = rcvr_spi(); + } while ((token == 0xFF) && Timer1); + if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */ + + do { /* Receive the data block into buffer */ + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + } while (btr -= 4); + rcvr_spi(); /* Discard CRC */ + rcvr_spi(); + + return TRUE; /* Return with success */ +} + + + +/*-----------------------------------------------------------------------*/ +/* Send a data packet to MMC */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +static +BOOL xmit_datablock ( + const BYTE *buff, /* 512 byte data block to be transmitted */ + BYTE token /* Data/Stop token */ +) +{ + BYTE resp, wc; + + + if (wait_ready() != 0xFF) return FALSE; + + xmit_spi(token); /* Xmit data token */ + if (token != 0xFD) { /* Is data token */ + wc = 0; + do { /* Xmit the 512 byte data block to MMC */ + xmit_spi(*buff++); + xmit_spi(*buff++); + } while (--wc); + xmit_spi(0xFF); /* CRC (Dummy) */ + xmit_spi(0xFF); + resp = rcvr_spi(); /* Reveive data response */ + if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */ + return FALSE; + } + + return TRUE; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Send a command packet to MMC */ +/*-----------------------------------------------------------------------*/ + +static +BYTE send_cmd ( + BYTE cmd, /* Command byte */ + DWORD arg /* Argument */ +) +{ + BYTE n, res; + + + if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ + cmd &= 0x7F; + res = send_cmd(CMD55, 0); + if (res > 1) return res; + } + + /* Select the card and wait for ready */ + deselect(); + if (!select()) return 0xFF; + + /* Send command packet */ + xmit_spi(cmd); /* Start + Command index */ + xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ + xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ + xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ + xmit_spi((BYTE)arg); /* Argument[7..0] */ + n = 0x01; /* Dummy CRC + Stop */ + if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ + if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + xmit_spi(n); + + /* Receive command response */ + if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */ + n = 10; /* Wait for a valid response in timeout of 10 attempts */ + do + res = rcvr_spi(); + while ((res & 0x80) && --n); + + return res; /* Return with the response value */ +} + + + +/*-------------------------------------------------------------------------- + + Public Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize ( + BYTE drv /* Physical drive nmuber (0) */ +) +{ + BYTE n, cmd, ty, ocr[4]; + + // Init SSP (clock low between frames, transition on leading edge) + sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge); + + gpioSetDir( SSP0_CSPORT, SSP0_CSPIN, gpioDirection_Output ); /* CS */ + gpioSetDir( CFG_SDCARD_CDPORT, CFG_SDCARD_CDPIN, gpioDirection_Input ); /* Card Detect */ + gpioSetPullup (&IOCON_PIO3_0, gpioPullupMode_Inactive); + + // Wait 20ms for card detect to stabilise + systickDelay(20); + + if (drv) return STA_NOINIT; /* Supports only single drive */ + if (Stat & STA_NODISK) return Stat; /* No card in the socket */ + + power_on(); /* Force socket power on */ + FCLK_SLOW(); + for (n = 100; n; n--) rcvr_spi(); /* 80 dummy clocks */ + + ty = 0; + if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ + Timer1 = 100; /* Initialization timeout of 1000 msec */ + if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ + while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ + if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */ + } + } + } else { /* SDSC or MMC */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDv1 */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMCv3 */ + } + while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ + if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ + ty = 0; + } + } + CardType = ty; + deselect(); + + if (ty) { /* Initialization succeded */ + Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + FCLK_FAST(); + } else { /* Initialization failed */ + power_off(); + } + + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0) */ +) +{ + if (drv) return STA_NOINIT; /* Supports only single drive */ + return Stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE *buff, /* Pointer to the data buffer to store read data */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block read */ + if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */ + && rcvr_datablock(buff, 512)) + count = 0; + } + else { /* Multiple block read */ + if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */ + do { + if (!rcvr_datablock(buff, 512)) break; + buff += 512; + } while (--count); + send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0) */ + const BYTE *buff, /* Pointer to the data to be written */ + DWORD sector, /* Start sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + if (Stat & STA_PROTECT) return RES_WRPRT; + + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + if (count == 1) { /* Single block write */ + if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ + && xmit_datablock(buff, 0xFE)) + count = 0; + } + else { /* Multiple block write */ + if (CardType & CT_SDC) send_cmd(ACMD23, count); + if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ + do { + if (!xmit_datablock(buff, 0xFC)) break; + buff += 512; + } while (--count); + if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ + count = 1; + } + } + deselect(); + + return count ? RES_ERROR : RES_OK; +} +#endif /* _READONLY == 0 */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL != 0 +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + BYTE n, csd[16], *ptr = buff; + WORD csize; + + + if (drv) return RES_PARERR; + + res = RES_ERROR; + + if (ctrl == CTRL_POWER) { + switch (*ptr) { + case 0: /* Sub control code == 0 (POWER_OFF) */ + if (chk_power()) + power_off(); /* Power off */ + res = RES_OK; + break; + case 1: /* Sub control code == 1 (POWER_ON) */ + power_on(); /* Power on */ + res = RES_OK; + break; + case 2: /* Sub control code == 2 (POWER_GET) */ + *(ptr+1) = (BYTE)chk_power(); + res = RES_OK; + break; + default : + res = RES_PARERR; + } + } + else { + if (Stat & STA_NOINIT) return RES_NOTRDY; + + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ + if (select()) { + res = RES_OK; + deselect(); + } + break; + + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { + if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */ + csize = csd[9] + ((WORD)csd[8] << 8) + 1; + *(DWORD*)buff = (DWORD)csize << 10; + } else { /* SDC ver 1.XX or MMC*/ + n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; + csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; + *(DWORD*)buff = (DWORD)csize << (n - 9); + } + res = RES_OK; + } + break; + + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; + + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + if (CardType & CT_SD2) { /* SDC ver 2.00 */ + if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ + rcvr_spi(); + if (rcvr_datablock(csd, 16)) { /* Read partial block */ + for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */ + *(DWORD*)buff = 16UL << (csd[10] >> 4); + res = RES_OK; + } + } + } else { /* SDC ver 1.XX or MMC */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ + if (CardType & CT_SD1) { /* SDC ver 1.XX */ + *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); + } else { /* MMC */ + *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); + } + res = RES_OK; + } + } + break; + + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ + *ptr = CardType; + res = RES_OK; + break; + + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ + if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ + if (send_cmd(CMD10, 0) == 0 /* READ_CID */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; + + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ + if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + for (n = 4; n; n--) *ptr++ = rcvr_spi(); + res = RES_OK; + } + break; + + case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */ + if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + rcvr_spi(); + if (rcvr_datablock(ptr, 64)) + res = RES_OK; + } + break; + + default: + res = RES_PARERR; + } + + deselect(); + } + + return res; +} +#endif /* _USE_IOCTL != 0 */ + + +/*-----------------------------------------------------------------------*/ +/* Device Timer Interrupt Procedure (Platform dependent) */ +/*-----------------------------------------------------------------------*/ +/* This function must be called in period of 10ms */ +/* Called from SysTick_Handler in systick.c */ + +void disk_timerproc (void) +{ + static BYTE pv; + BYTE n; + BYTE s; + + n = Timer1; /* 100Hz decrement timer */ + if (n) Timer1 = --n; + n = Timer2; + if (n) Timer2 = --n; + + n = pv; + pv = 0; + /* Sample card detect pin */ + pv = gpioGetValue(CFG_SDCARD_CDPORT, CFG_SDCARD_CDPIN); + + /* Have contacts stabled? */ + if (n == pv) + { + s = Stat; + + /* write protect NOT supported */ + + /* check card detect */ + if (!pv) /* (Socket empty) */ + s |= (STA_NODISK | STA_NOINIT); + else /* (Card inserted) */ + s &= ~STA_NODISK; + + Stat = s; + } +} + + diff --git a/drivers/lcd/bitmap/readme.txt b/drivers/lcd/bitmap/readme.txt new file mode 100644 index 0000000..8b144a0 --- /dev/null +++ b/drivers/lcd/bitmap/readme.txt @@ -0,0 +1,12 @@ +Bitmap LCDs +=========== + +This folder contains drivers for 1-bit graphic LCDs (128x64 pixel ST7565, etc.) +or text-only displays. They are placed in a seperate folder because the +drawing routines are handled quite differently than the generic drawing code +for 16-bit TFT LCDs. + +ST7565 Driver for 128x64 pixel I2C-based displays (available from + Adafruit Industries, for example). +SSD1306 Driver for 128x64 pixel OLED displays (also available from + Adafruit Industries). diff --git a/drivers/lcd/bitmap/ssd1306/ssd1306.c b/drivers/lcd/bitmap/ssd1306/ssd1306.c new file mode 100644 index 0000000..ce8872e --- /dev/null +++ b/drivers/lcd/bitmap/ssd1306/ssd1306.c @@ -0,0 +1,404 @@ +/**************************************************************************/ +/*! + @file ssd1306.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for 128x64 OLED display based on the SSD1306 controller. + + This driver is based on the SSD1306 Library from Limor Fried + (Adafruit Industries) at: https://github.com/adafruit/SSD1306 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "ssd1306.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" +#include "drivers/lcd/smallfonts.h" + +void ssd1306SendByte(uint8_t byte); + +#define CMD(c) do { gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 1 ); \ + gpioSetValue( SSD1306_DC_PORT, SSD1306_DC_PIN, 0 ); \ + gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 0 ); \ + ssd1306SendByte( c ); \ + gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 1 ); \ + } while (0); +#define DATA(c) do { gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 1 ); \ + gpioSetValue( SSD1306_DC_PORT, SSD1306_DC_PIN, 1 ); \ + gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 0 ); \ + ssd1306SendByte( c ); \ + gpioSetValue( SSD1306_CS_PORT, SSD1306_CS_PIN, 1 ); \ + } while (0); +#define DELAY(mS) do { systickDelay( mS / CFG_SYSTICK_DELAY_IN_MS ); } while(0); + +uint8_t buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8]; + +/**************************************************************************/ +/* Private Methods */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Simulates an SPI write using GPIO + + @param[in] byte + The byte to send +*/ +/**************************************************************************/ +void ssd1306SendByte(uint8_t byte) +{ + int8_t i; + + // Make sure clock pin starts high + gpioSetValue(SSD1306_SCLK_PORT, SSD1306_SCLK_PIN, 1); + + // Write from MSB to LSB + for (i=7; i>=0; i--) + { + // Set clock pin low + gpioSetValue(SSD1306_SCLK_PORT, SSD1306_SCLK_PIN, 0); + // Set data pin high or low depending on the value of the current bit + gpioSetValue(SSD1306_SDAT_PORT, SSD1306_SDAT_PIN, byte & (1 << i) ? 1 : 0); + // Set clock pin high + gpioSetValue(SSD1306_SCLK_PORT, SSD1306_SCLK_PIN, 1); + } +} + +/**************************************************************************/ +/*! + @brief Draws a single graphic character using the supplied font +*/ +/**************************************************************************/ +static void ssd1306DrawChar(uint16_t x, uint16_t y, uint8_t c, struct FONT_DEF font) +{ + uint8_t col, column[font.u8Width]; + + // Check if the requested character is available + if ((c >= font.u8FirstChar) && (c <= font.u8LastChar)) + { + // Retrieve appropriate columns from font data + for (col = 0; col < font.u8Width; col++) + { + column[col] = font.au8FontTable[((c - 32) * font.u8Width) + col]; // Get first column of appropriate character + } + } + else + { + // Requested character is not available in this font ... send a space instead + for (col = 0; col < font.u8Width; col++) + { + column[col] = 0xFF; // Send solid space + } + } + + // Render each column + uint16_t xoffset, yoffset; + for (xoffset = 0; xoffset < font.u8Width; xoffset++) + { + for (yoffset = 0; yoffset < (font.u8Height + 1); yoffset++) + { + uint8_t bit = 0x00; + bit = (column[xoffset] << (8 - (yoffset + 1))); // Shift current row bit left + bit = (bit >> 7); // Shift current row but right (results in 0x01 for black, and 0x00 for white) + if (bit) + { + ssd1306DrawPixel(x + xoffset, y + yoffset); + } + } + } +} + +/**************************************************************************/ +/* Public Methods */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Initialises the SSD1306 LCD display +*/ +/**************************************************************************/ +void ssd1306Init(uint8_t vccstate) +{ + // Set all pins to output + gpioSetDir(SSD1306_SCLK_PORT, SSD1306_SCLK_PIN, gpioDirection_Output); + gpioSetDir(SSD1306_SDAT_PORT, SSD1306_SDAT_PIN, gpioDirection_Output); + gpioSetDir(SSD1306_DC_PORT, SSD1306_DC_PIN, gpioDirection_Output); + gpioSetDir(SSD1306_RST_PORT, SSD1306_RST_PIN, gpioDirection_Output); + gpioSetDir(SSD1306_CS_PORT, SSD1306_CS_PIN, gpioDirection_Output); + + // Reset the LCD + gpioSetValue(SSD1306_RST_PORT, SSD1306_RST_PIN, 1); + DELAY(1); + gpioSetValue(SSD1306_RST_PORT, SSD1306_RST_PIN, 0); + DELAY(10); + gpioSetValue(SSD1306_RST_PORT, SSD1306_RST_PIN, 1); + + // Initialisation sequence + CMD(SSD1306_DISPLAYOFF); // 0xAE + CMD(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0 + CMD(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0 + CMD(SSD1306_SETSTARTLINE | 0x0); // line #0 + CMD(SSD1306_SETCONTRAST); // 0x81 + if (vccstate == SSD1306_EXTERNALVCC) + { CMD(0x9F) } + else + { CMD(0xCF) } + CMD(0xa1); // setment remap 95 to 0 (?) + CMD(SSD1306_NORMALDISPLAY); // 0xA6 + CMD(SSD1306_DISPLAYALLON_RESUME); // 0xA4 + CMD(SSD1306_SETMULTIPLEX); // 0xA8 + CMD(0x3F); // 0x3F 1/64 duty + CMD(SSD1306_SETDISPLAYOFFSET); // 0xD3 + CMD(0x0); // no offset + CMD(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 + CMD(0x80); // the suggested ratio 0x80 + CMD(SSD1306_SETPRECHARGE); // 0xd9 + if (vccstate == SSD1306_EXTERNALVCC) + { CMD(0x22) } + else + { CMD(0xF1) } + CMD(SSD1306_SETCOMPINS); // 0xDA + CMD(0x12); // disable COM left/right remap + CMD(SSD1306_SETVCOMDETECT); // 0xDB + CMD(0x40); // 0x20 is default? + CMD(SSD1306_MEMORYMODE); // 0x20 + CMD(0x00); // 0x0 act like ks0108 + CMD(SSD1306_SEGREMAP | 0x1); + CMD(SSD1306_COMSCANDEC); + CMD(SSD1306_CHARGEPUMP); //0x8D + if (vccstate == SSD1306_EXTERNALVCC) + { CMD(0x10) } + else + { CMD(0x14) } + + // Enabled the OLED panel + CMD(SSD1306_DISPLAYON); +} + +/**************************************************************************/ +/*! + @brief Draws a single pixel in image buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) +*/ +/**************************************************************************/ +void ssd1306DrawPixel(uint8_t x, uint8_t y) +{ + if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT)) + return; + + buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << y%8); +} + +/**************************************************************************/ +/*! + @brief Clears a single pixel in image buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) +*/ +/**************************************************************************/ +void ssd1306ClearPixel(uint8_t x, uint8_t y) +{ + if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT)) + return; + + buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << y%8); +} + +/**************************************************************************/ +/*! + @brief Gets the value (1 or 0) of the specified pixel from the buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) + + @return 1 if the pixel is enabled, 0 if disabled +*/ +/**************************************************************************/ +uint8_t ssd1306GetPixel(uint8_t x, uint8_t y) +{ + if ((x >= SSD1306_LCDWIDTH) || (y >=SSD1306_LCDHEIGHT)) return 0; + return buffer[x+ (y/8)*SSD1306_LCDWIDTH] & (1 << y%8) ? 1 : 0; +} + +/**************************************************************************/ +/*! + @brief Clears the screen +*/ +/**************************************************************************/ +void ssd1306ClearScreen() +{ + memset(buffer, 0, 1024); +} + +/**************************************************************************/ +/*! + @brief Renders the contents of the pixel buffer on the LCD +*/ +/**************************************************************************/ +void ssd1306Refresh(void) +{ + CMD(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0 + CMD(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0 + CMD(SSD1306_SETSTARTLINE | 0x0); // line #0 + + uint16_t i; + for (i=0; i<1024; i++) + { + DATA(buffer[i]); + } +} + +/**************************************************************************/ +/*! + @brief Draws a string using the supplied font data. + + @param[in] x + Starting x co-ordinate + @param[in] y + Starting y co-ordinate + @param[in] text + The string to render + @param[in] font + Pointer to the FONT_DEF to use when drawing the string + + @section Example + + @code + + #include "drivers/lcd/bitmap/ssd1306/ssd1306.h" + #include "drivers/lcd/smallfonts.h" + + // Configure the pins and initialise the LCD screen + ssd1306Init(); + + // Render some text on the screen + ssd1306DrawString(1, 10, "5x8 System", Font_System5x8); + ssd1306DrawString(1, 20, "7x8 System", Font_System7x8); + + // Refresh the screen to see the results + ssd1306Refresh(); + + @endcode +*/ +/**************************************************************************/ +void ssd1306DrawString(uint16_t x, uint16_t y, char* text, struct FONT_DEF font) +{ + uint8_t l; + for (l = 0; l < strlen(text); l++) + { + ssd1306DrawChar(x + (l * (font.u8Width + 1)), y, text[l], font); + } +} + +/**************************************************************************/ +/*! + @brief Shifts the contents of the frame buffer up the specified + number of pixels + + @param[in] height + The number of pixels to shift the frame buffer up, leaving + a blank space at the bottom of the frame buffer x pixels + high + + @section Example + + @code + + #include "drivers/lcd/bitmap/ssd1306/ssd1306.h" + #include "drivers/lcd/smallfonts.h" + + // Configure the pins and initialise the LCD screen + ssd1306Init(); + + // Enable the backlight + ssd1306BLEnable(); + + // Continually write some text, scrolling upward one line each time + while (1) + { + // Shift the buffer up 8 pixels (adjust for font-height) + ssd1306ShiftFrameBuffer(8); + // Render some text on the screen with different fonts + ssd1306DrawString(1, 56, "INSERT TEXT HERE", Font_System5x8); + // Refresh the screen to see the results + ssd1306Refresh(); + // Wait a bit before writing the next line + systickDelay(1000); + } + + @endcode +*/ +/**************************************************************************/ +void ssd1306ShiftFrameBuffer( uint8_t height ) +{ + if (height == 0) return; + if (height >= SSD1306_LCDHEIGHT) + { + // Clear the entire frame buffer + ssd1306ClearScreen(); + return; + } + + // This is horribly inefficient, but at least easy to understand + // In a production environment, this should be significantly optimised + + uint8_t y, x; + for (y = 0; y < SSD1306_LCDHEIGHT; y++) + { + for (x = 0; x < SSD1306_LCDWIDTH; x++) + { + if ((SSD1306_LCDHEIGHT - 1) - y > height) + { + // Shift height from further ahead in the buffer + ssd1306GetPixel(x, y + height) ? ssd1306DrawPixel(x, y) : ssd1306ClearPixel(x, y); + } + else + { + // Clear the entire line + ssd1306ClearPixel(x, y); + } + } + } +} diff --git a/drivers/lcd/bitmap/ssd1306/ssd1306.h b/drivers/lcd/bitmap/ssd1306/ssd1306.h new file mode 100644 index 0000000..510efa9 --- /dev/null +++ b/drivers/lcd/bitmap/ssd1306/ssd1306.h @@ -0,0 +1,95 @@ +/**************************************************************************/ +/*! + @file ssd1306.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __SSD1306_H__ +#define __SSD1306_H__ + +#include "projectconfig.h" + +#include "drivers/lcd/smallfonts.h" + +// Pin Definitions +#define SSD1306_DC_PORT (2) // Data/Command +#define SSD1306_DC_PIN (1) +#define SSD1306_RST_PORT (2) // Reset +#define SSD1306_RST_PIN (2) +#define SSD1306_CS_PORT (2) // Select +#define SSD1306_CS_PIN (3) +#define SSD1306_SCLK_PORT (2) // Serial Clock +#define SSD1306_SCLK_PIN (5) +#define SSD1306_SDAT_PORT (2) // Serial Data +#define SSD1306_SDAT_PIN (6) + +#define SSD1306_LCDWIDTH 128 +#define SSD1306_LCDHEIGHT 64 + +// Commands +#define SSD1306_SETCONTRAST 0x81 +#define SSD1306_DISPLAYALLON_RESUME 0xA4 +#define SSD1306_DISPLAYALLON 0xA5 +#define SSD1306_NORMALDISPLAY 0xA6 +#define SSD1306_INVERTDISPLAY 0xA7 +#define SSD1306_DISPLAYOFF 0xAE +#define SSD1306_DISPLAYON 0xAF +#define SSD1306_SETDISPLAYOFFSET 0xD3 +#define SSD1306_SETCOMPINS 0xDA +#define SSD1306_SETVCOMDETECT 0xDB +#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 +#define SSD1306_SETPRECHARGE 0xD9 +#define SSD1306_SETMULTIPLEX 0xA8 +#define SSD1306_SETLOWCOLUMN 0x00 +#define SSD1306_SETHIGHCOLUMN 0x10 +#define SSD1306_SETSTARTLINE 0x40 +#define SSD1306_MEMORYMODE 0x20 +#define SSD1306_COMSCANINC 0xC0 +#define SSD1306_COMSCANDEC 0xC8 +#define SSD1306_SEGREMAP 0xA0 +#define SSD1306_CHARGEPUMP 0x8D +#define SSD1306_EXTERNALVCC 0x1 +#define SSD1306_SWITCHCAPVCC 0x2 + +// Initialisation/Config Prototypes +void ssd1306Init ( uint8_t vccstate ); +void ssd1306DrawPixel ( uint8_t x, uint8_t y ); +void ssd1306ClearPixel ( uint8_t x, uint8_t y ); +uint8_t ssd1306GetPixel ( uint8_t x, uint8_t y ); +void ssd1306ClearScreen ( void ); +void ssd1306Refresh ( void ); +void ssd1306DrawString( uint16_t x, uint16_t y, char* text, struct FONT_DEF font ); +void ssd1306ShiftFrameBuffer( uint8_t height ); + +#endif diff --git a/drivers/lcd/bitmap/st7565/st7565.c b/drivers/lcd/bitmap/st7565/st7565.c new file mode 100644 index 0000000..b0995ac --- /dev/null +++ b/drivers/lcd/bitmap/st7565/st7565.c @@ -0,0 +1,445 @@ +/**************************************************************************/ +/*! + @file ST7565.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for 128x64 pixel display based on the ST7565 LCD controller. + + This driver is based on the ST7565 Library from Limor Fried + (Adafruit Industries) at: http://github.com/adafruit/ST7565-LCD/ + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "st7565.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" +#include "drivers/lcd/smallfonts.h" + +void sendByte(uint8_t byte); + +#define CMD(c) do { gpioSetValue( ST7565_A0_PORT, ST7565_A0_PIN, 0 ); sendByte( c ); } while (0); +#define DATA(d) do { gpioSetValue( ST7565_A0_PORT, ST7565_A0_PIN, 1 ); sendByte( d ); } while (0); +#define DELAY(mS) do { systickDelay( mS / CFG_SYSTICK_DELAY_IN_MS ); } while(0); + +uint8_t buffer[128*64/8]; + +/**************************************************************************/ +/* Private Methods */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Renders the buffer contents + + @param[in] buffer + Pointer to the buffer containing the raw pixel data +*/ +/**************************************************************************/ +void writeBuffer(uint8_t *buffer) +{ + uint8_t c, p; + int pagemap[] = { 3, 2, 1, 0, 7, 6, 5, 4 }; + + for(p = 0; p < 8; p++) + { + CMD(ST7565_CMD_SET_PAGE | pagemap[p]); + CMD(ST7565_CMD_SET_COLUMN_LOWER | (0x0 & 0xf)); + CMD(ST7565_CMD_SET_COLUMN_UPPER | ((0x0 >> 4) & 0xf)); + CMD(ST7565_CMD_RMW); + DATA(0xff); + + for(c = 0; c < 128; c++) + { + DATA(buffer[(128*p)+c]); + } + } +} + +/**************************************************************************/ +/*! + @brief Simulates an SPI write using GPIO + + @param[in] byte + The byte to send +*/ +/**************************************************************************/ +void sendByte(uint8_t byte) +{ + int8_t i; + + // Note: This code can be optimised to avoid the branches by setting + // GPIO registers directly, but we'll leave it as is for the moment + // for simplicity sake + + // Make sure clock pin starts high + gpioSetValue(ST7565_SCLK_PORT, ST7565_SCLK_PIN, 1); + + // Write from MSB to LSB + for (i=7; i>=0; i--) + { + // Set clock pin low + gpioSetValue(ST7565_SCLK_PORT, ST7565_SCLK_PIN, 0); + // Set data pin high or low depending on the value of the current bit + gpioSetValue(ST7565_SDAT_PORT, ST7565_SDAT_PIN, byte & (1 << i) ? 1 : 0); + // Set clock pin high + gpioSetValue(ST7565_SCLK_PORT, ST7565_SCLK_PIN, 1); + } +} + +/**************************************************************************/ +/*! + @brief Draws a single graphic character using the supplied font +*/ +/**************************************************************************/ +void drawChar(uint16_t x, uint16_t y, uint8_t c, struct FONT_DEF font) +{ + uint8_t col, column[font.u8Width]; + + // Check if the requested character is available + if ((c >= font.u8FirstChar) && (c <= font.u8LastChar)) + { + // Retrieve appropriate columns from font data + for (col = 0; col < font.u8Width; col++) + { + column[col] = font.au8FontTable[((c - 32) * font.u8Width) + col]; // Get first column of appropriate character + } + } + else + { + // Requested character is not available in this font ... send a space instead + for (col = 0; col < font.u8Width; col++) + { + column[col] = 0xFF; // Send solid space + } + } + + // Render each column + uint16_t xoffset, yoffset; + for (xoffset = 0; xoffset < font.u8Width; xoffset++) + { + for (yoffset = 0; yoffset < (font.u8Height + 1); yoffset++) + { + uint8_t bit = 0x00; + bit = (column[xoffset] << (8 - (yoffset + 1))); // Shift current row bit left + bit = (bit >> 7); // Shift current row but right (results in 0x01 for black, and 0x00 for white) + if (bit) + { + st7565DrawPixel(x + xoffset, y + yoffset); + } + } + } +} + +/**************************************************************************/ +/* Public Methods */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Initialises the ST7565 LCD display +*/ +/**************************************************************************/ +void st7565Init(void) +{ + // Note: This can be optimised to set all pins to output and high + // in two commands by manipulating the registers directly (assuming + // that the pins are located in the same GPIO bank). The code is left + // as is for clarity sake in case the pins are not all located in the + // same bank. + + // Set clock pin to output and high + gpioSetDir(ST7565_SCLK_PORT, ST7565_SCLK_PIN, 1); + gpioSetValue(ST7565_SCLK_PORT, ST7565_SCLK_PIN, 1); + + // Set data pin to output and high + gpioSetDir(ST7565_SDAT_PORT, ST7565_SDAT_PIN, 1); + gpioSetValue(ST7565_SDAT_PORT, ST7565_SDAT_PIN, 1); + + // Configure backlight pin to output and set high (off) + gpioSetDir(ST7565_BL_PORT, ST7565_BL_PIN, 1); + gpioSetValue(ST7565_BL_PORT, ST7565_BL_PIN, 1); + + // Configure A0 pin to output and set high + gpioSetDir(ST7565_A0_PORT, ST7565_A0_PIN, 1); + gpioSetValue(ST7565_A0_PORT, ST7565_A0_PIN, 1); + + // Configure Reset pin and set high + gpioSetDir(ST7565_RST_PORT, ST7565_RST_PIN, 1); + gpioSetValue(ST7565_RST_PORT, ST7565_RST_PIN, 1); + + // Configure select pin and set high + gpioSetDir(ST7565_CS_PORT, ST7565_CS_PIN, 1); + gpioSetValue(ST7565_CS_PORT, ST7565_CS_PIN, 1); + + // Reset + gpioSetValue(ST7565_CS_PORT, ST7565_CS_PIN, 0); // Set CS low + gpioSetValue(ST7565_RST_PORT, ST7565_RST_PIN, 0); // Set reset low + DELAY(500 / CFG_SYSTICK_DELAY_IN_MS); // Wait 500mS + gpioSetValue(ST7565_RST_PORT, ST7565_RST_PIN, 1); // Set reset high + + // Configure Display + CMD(ST7565_CMD_SET_BIAS_7); // LCD Bias Select + CMD(ST7565_CMD_SET_ADC_NORMAL); // ADC Select + CMD(ST7565_CMD_SET_COM_NORMAL); // SHL Select + CMD(ST7565_CMD_SET_DISP_START_LINE); // Initial Display Line + CMD(ST7565_CMD_SET_POWER_CONTROL | 0x04); // Turn on voltage converter (VC=1, VR=0, VF=0) + DELAY(50 / CFG_SYSTICK_DELAY_IN_MS); // Wait 50mS + CMD(ST7565_CMD_SET_POWER_CONTROL | 0x06); // Turn on voltage regulator (VC=1, VR=1, VF=0) + DELAY(50 / CFG_SYSTICK_DELAY_IN_MS); // Wait 50mS + CMD(ST7565_CMD_SET_POWER_CONTROL | 0x07); // Turn on voltage follower + DELAY(10 / CFG_SYSTICK_DELAY_IN_MS); // Wait 10mS + CMD(ST7565_CMD_SET_RESISTOR_RATIO | 0x6); // Set LCD operating voltage + + // Turn display on + CMD(ST7565_CMD_DISPLAY_ON); + CMD(ST7565_CMD_SET_ALLPTS_NORMAL); + st7565SetBrightness(0x18); +} + +/**************************************************************************/ +/*! + @brief Enables or disables the backlight +*/ +/**************************************************************************/ +void st7565Backlight(bool state) +{ + gpioSetValue( ST7565_BL_PORT, ST7565_BL_PIN, state ? 0 : 1 ); +} + +/**************************************************************************/ +/*! + @brief Sets the display brightness +*/ +/**************************************************************************/ +void st7565SetBrightness(uint8_t val) +{ + CMD(ST7565_CMD_SET_VOLUME_FIRST); + CMD(ST7565_CMD_SET_VOLUME_SECOND | (val & 0x3f)); +} + +/**************************************************************************/ +/*! + @brief Clears the screen +*/ +/**************************************************************************/ +void st7565ClearScreen(void) +{ + memset(&buffer, 0x00, 128*64/8); +} + +/**************************************************************************/ +/*! + @brief Renders the contents of the pixel buffer on the LCD +*/ +/**************************************************************************/ +void st7565Refresh(void) +{ + writeBuffer(buffer); +} + +/**************************************************************************/ +/*! + @brief Draws a single pixel in image buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) +*/ +/**************************************************************************/ +void st7565DrawPixel(uint8_t x, uint8_t y) +{ + if ((x >= 128) || (y >= 64)) + return; + + // x is which column + buffer[x+ (y/8)*128] |= (1 << (7-(y%8))); +} + +/**************************************************************************/ +/*! + @brief Clears a single pixel in image buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) +*/ +/**************************************************************************/ +void st7565ClearPixel(uint8_t x, uint8_t y) +{ + if ((x >= 128) || (y >= 64)) + return; + + // x is which column + buffer[x+ (y/8)*128] &= ~(1 << (7-(y%8))); +} + +/**************************************************************************/ +/*! + @brief Gets the value (1 or 0) of the specified pixel from the buffer + + @param[in] x + The x position (0..127) + @param[in] y + The y position (0..63) + + @return 1 if the pixel is enabled, 0 if disabled +*/ +/**************************************************************************/ +uint8_t st7565GetPixel(uint8_t x, uint8_t y) +{ + if ((x >= 128) || (y >= 64)) return 0; + return buffer[x+ (y/8)*128] & (1 << (7-(y%8))); +} + +/**************************************************************************/ +/*! + @brief Draws a string using the supplied font data. + + @param[in] x + Starting x co-ordinate + @param[in] y + Starting y co-ordinate + @param[in] text + The string to render + @param[in] font + Pointer to the FONT_DEF to use when drawing the string + + @section Example + + @code + + #include "drivers/lcd/bitmap/st7565/st7565.h" + #include "drivers/lcd/smallfonts.h" + + // Configure the pins and initialise the LCD screen + st7565Init(); + + // Enable the backlight + st7565BLEnable(); + + // Render some text on the screen with different fonts + st7565DrawString(1, 1, "3X6 SYSTEM", Font_System3x6); // 3x6 is UPPER CASE only + st7565DrawString(1, 10, "5x8 System", Font_System5x8); + st7565DrawString(1, 20, "7x8 System", Font_System7x8); + + // Refresh the screen to see the results + st7565Refresh(); + + @endcode +*/ +/**************************************************************************/ +void st7565DrawString(uint16_t x, uint16_t y, char* text, struct FONT_DEF font) +{ + uint8_t l; + for (l = 0; l < strlen(text); l++) + { + drawChar(x + (l * (font.u8Width + 1)), y, text[l], font); + } +} + +/**************************************************************************/ +/*! + @brief Shifts the contents of the frame buffer up the specified + number of pixels + + @param[in] height + The number of pixels to shift the frame buffer up, leaving + a blank space at the bottom of the frame buffer x pixels + high + + @section Example + + @code + + #include "drivers/lcd/bitmap/st7565/st7565.h" + #include "drivers/lcd/smallfonts.h" + + // Configure the pins and initialise the LCD screen + st7565Init(); + + // Enable the backlight + st7565BLEnable(); + + // Continually write some text, scrolling upward one line each time + while (1) + { + // Shift the buffer up 8 pixels (adjust for font-height) + st7565ShiftFrameBuffer(8); + // Render some text on the screen with different fonts + st7565DrawString(1, 56, "INSERT TEXT HERE", Font_System3x6); // 3x6 is UPPER CASE only + // Refresh the screen to see the results + st7565Refresh(); + // Wait a bit before writing the next line + systickDelay(1000); + } + + @endcode +*/ +/**************************************************************************/ +void st7565ShiftFrameBuffer( uint8_t height ) +{ + if (height == 0) return; + if (height >= 64) + { + // Clear the entire frame buffer + st7565ClearScreen(); + return; + } + + // This is horribly inefficient, but at least easy to understand + // In a production environment, this should be significantly optimised + + uint8_t y, x; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 128; x++) + { + if (63 - y > height) + { + // Shift height from further ahead in the buffer + st7565GetPixel(x, y + height) ? st7565DrawPixel(x, y) : st7565ClearPixel(x, y); + } + else + { + // Clear the entire line + st7565ClearPixel(x, y); + } + } + } +} + diff --git a/drivers/lcd/bitmap/st7565/st7565.h b/drivers/lcd/bitmap/st7565/st7565.h new file mode 100644 index 0000000..c27a06f --- /dev/null +++ b/drivers/lcd/bitmap/st7565/st7565.h @@ -0,0 +1,109 @@ +/**************************************************************************/ +/*! + @file ST7565.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __ST7565_H__ +#define __ST7565_H__ + +#include "projectconfig.h" + +#include "drivers/lcd/smallfonts.h" + +// Pin Definitions +#define ST7565_A0_PORT (2) // Register Select Pin (A0) +#define ST7565_A0_PIN (1) +#define ST7565_RST_PORT (2) // Reset +#define ST7565_RST_PIN (2) +#define ST7565_CS_PORT (2) // Select +#define ST7565_CS_PIN (3) +#define ST7565_BL_PORT (2) // Backlight +#define ST7565_BL_PIN (4) +#define ST7565_SCLK_PORT (2) // Serial Clock +#define ST7565_SCLK_PIN (5) +#define ST7565_SDAT_PORT (2) // Serial Data +#define ST7565_SDAT_PIN (6) + +// Commands +#define ST7565_CMD_DISPLAY_OFF 0xAE +#define ST7565_CMD_DISPLAY_ON 0xAF +#define ST7565_CMD_SET_DISP_START_LINE 0x40 +#define ST7565_CMD_SET_PAGE 0xB0 +#define ST7565_CMD_SET_COLUMN_UPPER 0x10 +#define ST7565_CMD_SET_COLUMN_LOWER 0x00 +#define ST7565_CMD_SET_ADC_NORMAL 0xA0 +#define ST7565_CMD_SET_ADC_REVERSE 0xA1 +#define ST7565_CMD_SET_DISP_NORMAL 0xA6 +#define ST7565_CMD_SET_DISP_REVERSE 0xA7 +#define ST7565_CMD_SET_ALLPTS_NORMAL 0xA4 +#define ST7565_CMD_SET_ALLPTS_ON 0xA5 +#define ST7565_CMD_SET_BIAS_9 0xA2 +#define ST7565_CMD_SET_BIAS_7 0xA3 +#define ST7565_CMD_RMW 0xE0 +#define ST7565_CMD_RMW_CLEAR 0xEE +#define ST7565_CMD_INTERNAL_RESET 0xE2 +#define ST7565_CMD_SET_COM_NORMAL 0xC0 +#define ST7565_CMD_SET_COM_REVERSE 0xC8 +#define ST7565_CMD_SET_POWER_CONTROL 0x28 +#define ST7565_CMD_SET_RESISTOR_RATIO 0x20 +#define ST7565_CMD_SET_VOLUME_FIRST 0x81 +#define ST7565_CMD_SET_VOLUME_SECOND 0 +#define ST7565_CMD_SET_STATIC_OFF 0xAC +#define ST7565_CMD_SET_STATIC_ON 0xAD +#define ST7565_CMD_SET_STATIC_REG 0x0 +#define ST7565_CMD_SET_BOOSTER_FIRST 0xF8 +#define ST7565_CMD_SET_BOOSTER_234 0 +#define ST7565_CMD_SET_BOOSTER_5 1 +#define ST7565_CMD_SET_BOOSTER_6 3 +#define ST7565_CMD_NOP 0xE3 +#define ST7565_CMD_TEST 0xF0 + +// Initialisation/Config Prototypes +void st7565Init( void ); +void st7565Command( uint8_t c ); +void st7565Data( uint8_t d ); +void st7565SetBrightness( uint8_t val ); + +// Backlight Prototypes +void st7565Backlight(bool state); + +// Drawing Prototypes +void st7565ClearScreen( void ); +void st7565Refresh( void ); +void st7565DrawPixel( uint8_t x, uint8_t y ); +void st7565ClearPixel( uint8_t x, uint8_t y ); +uint8_t st7565GetPixel( uint8_t x, uint8_t y ); +void st7565DrawString( uint16_t x, uint16_t y, char* text, struct FONT_DEF font ); +void st7565ShiftFrameBuffer( uint8_t pixels ); + +#endif diff --git a/drivers/lcd/icons16.h b/drivers/lcd/icons16.h new file mode 100644 index 0000000..e37f074 --- /dev/null +++ b/drivers/lcd/icons16.h @@ -0,0 +1,62 @@ +/**************************************************************************/ +/*! + @file icons16.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +/* + All icons have been converted from the GentleFace Toolbar Icon Set, + licensed under the Creative Commons Attribution-NonCommercial License. + for more information see: http://www.gentleface.com/free_icon_set.html +*/ + +// Each icon used will consume 32 bytes of flash memory + +#ifndef __ICONS16_H__ +#define __ICONS16_H__ + +uint16_t icons16_alert[16] = { 0x0000, 0x0000, 0x0180, 0x03C0, 0x03C0, 0x0660, 0x0660, 0x0E70, 0x0E70, 0x1E78, 0x3E7C, 0x3FFC, 0x7E7E, 0x7E7E, 0xFFFF, 0x0000 }; +uint16_t icons16_alert_interior[16] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, 0x0180, 0x0180, 0x0000, 0x0000 }; +uint16_t icons16_info[16] = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3F3E, 0x7F3F, 0x7FFF, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x3F3E, 0x1FFC, 0x0FF8, 0x07F0 }; +uint16_t icons16_info_interior[16] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0, 0x0000, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000 }; +uint16_t icons16_failed[16] = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3FFE, 0x79CF, 0x788F, 0x7C1F, 0x7E3F, 0x7C1F, 0x788F, 0x79CF, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0 }; +uint16_t icons16_failed_interior[16] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0630, 0x0770, 0x03E0, 0x01C0, 0x03E0, 0x0770, 0x0630, 0x0000, 0x0000, 0x0000, 0x0000 }; +uint16_t icons16_passed[16] = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3FFE, 0x7FEF, 0x7FC7, 0x7F8F, 0x731F, 0x783F, 0x7C7F, 0x7EFF, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0 }; +uint16_t icons16_passed_interior[16] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0038, 0x0070, 0x0CE0, 0x07C0, 0x0380, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000 }; +uint16_t icons16_pointer[16] = { 0x07C0, 0x1FF0, 0x3FF8, 0x3FF8, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x3FF8, 0x1FF0, 0x0FE0, 0x07C0, 0x0380, 0x0100 }; +uint16_t icons16_pointer_dot[16] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0380, 0x07C0, 0x07C0, 0x07C0, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; +uint16_t icons16_tag[16] = { 0xFF00, 0xFF80, 0xCFC0, 0xCFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0x7FFE, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0, 0x03E0, 0x01C0, 0x0000 }; +uint16_t icons16_tag_dot[16] = { 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; +uint16_t icons16_tools[16] = { 0x118C, 0x118C, 0x11FC, 0x11FC, 0x10F8, 0x1070, 0x1070, 0x3870, 0x1070, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870 }; + +#endif diff --git a/drivers/lcd/smallfonts.c b/drivers/lcd/smallfonts.c new file mode 100644 index 0000000..5a185f8 --- /dev/null +++ b/drivers/lcd/smallfonts.c @@ -0,0 +1,556 @@ +/* Partially based on original code for the KS0108 by Stephane Rey */ + +/**************************************************************************/ +/*! + @file smallfonts.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "sysdefs.h" +#include "smallfonts.h" + +/* Global variables */ +const struct FONT_DEF Font_System3x6 = {3, 6, 32, 96, au8FontSystem3x6}; +const struct FONT_DEF Font_System5x8 = {5, 8, 32, 128, au8FontSystem5x8}; +const struct FONT_DEF Font_System7x8 = {7, 8, 32, 128, au8FontSystem7x8}; +const struct FONT_DEF Font_8x8 = {8, 8, 32, 128, au8Font8x8}; +const struct FONT_DEF Font_8x8Thin = {8, 8, 32, 128, au8Font8x8Thin}; + +/* System 3x6 - UPPER CASE ONLY */ +const uint8_t au8FontSystem3x6[]= { + 0x00,0x00,0x00, /* Space */ + 0x00,0x5C,0x00, /* ! */ + 0x0C,0x00,0x0C, /* " */ + 0x7C,0x28,0x7C, /* # */ + 0x7C,0x44,0x7C, /* 0x */ + 0x24,0x10,0x48, /* % */ + 0x28,0x54,0x08, /* & */ + 0x00,0x0C,0x00, /* ' */ + 0x38,0x44,0x00, /* ( */ + 0x44,0x38,0x00, /* ) */ + 0x20,0x10,0x08, /* // */ + 0x10,0x38,0x10, /* + */ + 0x80,0x40,0x00, /* , */ + 0x10,0x10,0x10, /* - */ + 0x00,0x40,0x00, /* . */ + 0x20,0x10,0x08, /* / */ + 0x38,0x44,0x38, /* 0 */ + 0x00,0x7C,0x00, /* 1 */ + 0x64,0x54,0x48, /* 2 */ + 0x44,0x54,0x28, /* 3 */ + 0x1C,0x10,0x7C, /* 4 */ + 0x4C,0x54,0x24, /* 5 */ + 0x38,0x54,0x20, /* 6 */ + 0x04,0x74,0x0C, /* 7 */ + 0x28,0x54,0x28, /* 8 */ + 0x08,0x54,0x38, /* 9 */ + 0x00,0x50,0x00, /* : */ + 0x80,0x50,0x00, /* ; */ + 0x10,0x28,0x44, /* < */ + 0x28,0x28,0x28, /* = */ + 0x44,0x28,0x10, /* > */ + 0x04,0x54,0x08, /* ? */ + 0x38,0x4C,0x5C, /* @ */ + 0x78,0x14,0x78, /* A */ + 0x7C,0x54,0x28, /* B */ + 0x38,0x44,0x44, /* C */ + 0x7C,0x44,0x38, /* D */ + 0x7C,0x54,0x44, /* E */ + 0x7C,0x14,0x04, /* F */ + 0x38,0x44,0x34, /* G */ + 0x7C,0x10,0x7C, /* H */ + 0x00,0x7C,0x00, /* I */ + 0x20,0x40,0x3C, /* J */ + 0x7C,0x10,0x6C, /* K */ + 0x7C,0x40,0x40, /* L */ + 0x7C,0x08,0x7C, /* M */ + 0x7C,0x04,0x7C, /* N */ + 0x7C,0x44,0x7C, /* O */ + 0x7C,0x14,0x08, /* P */ + 0x38,0x44,0x78, /* Q */ + 0x7C,0x14,0x68, /* R */ + 0x48,0x54,0x24, /* S */ + 0x04,0x7C,0x04, /* T */ + 0x7C,0x40,0x7C, /* U */ + 0x3C,0x40,0x3C, /* V */ + 0x7C,0x20,0x7C, /* W */ + 0x6C,0x10,0x6C, /* X */ + 0x1C,0x60,0x1C, /* Y */ + 0x64,0x54,0x4C, /* Z */ + 0x7C,0x44,0x00, /* [ */ + 0x08,0x10,0x20, /* \ */ + 0x44,0x7C,0x00, /* ] */ + 0x08,0x04,0x08, /* ^ */ + 0x80,0x80,0x80, /* _ */ + 0x04,0x08,0x00 /* ` */ +}; + +/* System 5x8 */ +const uint8_t au8FontSystem5x8[]= +{ + 0x00,0x00,0x00,0x00,0x00, /* Space */ + 0x00,0x00,0x4f,0x00,0x00, /* ! */ + 0x00,0x07,0x00,0x07,0x00, /* " */ + 0x14,0x7f,0x14,0x7f,0x14, /* # */ + 0x24,0x2a,0x7f,0x2a,0x12, /* 0x */ + 0x23,0x13,0x08,0x64,0x62, /* % */ + 0x36,0x49,0x55,0x22,0x20, /* & */ + 0x00,0x05,0x03,0x00,0x00, /* ' */ + 0x00,0x1c,0x22,0x41,0x00, /* ( */ + 0x00,0x41,0x22,0x1c,0x00, /* ) */ + 0x14,0x08,0x3e,0x08,0x14, /* // */ + 0x08,0x08,0x3e,0x08,0x08, /* + */ + 0x50,0x30,0x00,0x00,0x00, /* , */ + 0x08,0x08,0x08,0x08,0x08, /* - */ + 0x00,0x60,0x60,0x00,0x00, /* . */ + 0x20,0x10,0x08,0x04,0x02, /* / */ + 0x3e,0x51,0x49,0x45,0x3e, /* 0 */ + 0x00,0x42,0x7f,0x40,0x00, /* 1 */ + 0x42,0x61,0x51,0x49,0x46, /* 2 */ + 0x21,0x41,0x45,0x4b,0x31, /* 3 */ + 0x18,0x14,0x12,0x7f,0x10, /* 4 */ + 0x27,0x45,0x45,0x45,0x39, /* 5 */ + 0x3c,0x4a,0x49,0x49,0x30, /* 6 */ + 0x01,0x71,0x09,0x05,0x03, /* 7 */ + 0x36,0x49,0x49,0x49,0x36, /* 8 */ + 0x06,0x49,0x49,0x29,0x1e, /* 9 */ + 0x00,0x36,0x36,0x00,0x00, /* : */ + 0x00,0x56,0x36,0x00,0x00, /* ; */ + 0x08,0x14,0x22,0x41,0x00, /* < */ + 0x14,0x14,0x14,0x14,0x14, /* = */ + 0x00,0x41,0x22,0x14,0x08, /* > */ + 0x02,0x01,0x51,0x09,0x06, /* ? */ + 0x3e,0x41,0x5d,0x55,0x1e, /* @ */ + 0x7e,0x11,0x11,0x11,0x7e, /* A */ + 0x7f,0x49,0x49,0x49,0x36, /* B */ + 0x3e,0x41,0x41,0x41,0x22, /* C */ + 0x7f,0x41,0x41,0x22,0x1c, /* D */ + 0x7f,0x49,0x49,0x49,0x41, /* E */ + 0x7f,0x09,0x09,0x09,0x01, /* F */ + 0x3e,0x41,0x49,0x49,0x7a, /* G */ + 0x7f,0x08,0x08,0x08,0x7f, /* H */ + 0x00,0x41,0x7f,0x41,0x00, /* I */ + 0x20,0x40,0x41,0x3f,0x01, /* J */ + 0x7f,0x08,0x14,0x22,0x41, /* K */ + 0x7f,0x40,0x40,0x40,0x40, /* L */ + 0x7f,0x02,0x0c,0x02,0x7f, /* M */ + 0x7f,0x04,0x08,0x10,0x7f, /* N */ + 0x3e,0x41,0x41,0x41,0x3e, /* O */ + 0x7f,0x09,0x09,0x09,0x06, /* P */ + 0x3e,0x41,0x51,0x21,0x5e, /* Q */ + 0x7f,0x09,0x19,0x29,0x46, /* R */ + 0x26,0x49,0x49,0x49,0x32, /* S */ + 0x01,0x01,0x7f,0x01,0x01, /* T */ + 0x3f,0x40,0x40,0x40,0x3f, /* U */ + 0x1f,0x20,0x40,0x20,0x1f, /* V */ + 0x3f,0x40,0x38,0x40,0x3f, /* W */ + 0x63,0x14,0x08,0x14,0x63, /* X */ + 0x07,0x08,0x70,0x08,0x07, /* Y */ + 0x61,0x51,0x49,0x45,0x43, /* Z */ + 0x00,0x7f,0x41,0x41,0x00, /* [ */ + 0x02,0x04,0x08,0x10,0x20, /* \ */ + 0x00,0x41,0x41,0x7f,0x00, /* ] */ + 0x04,0x02,0x01,0x02,0x04, /* ^ */ + 0x40,0x40,0x40,0x40,0x40, /* _ */ + 0x00,0x00,0x03,0x05,0x00, /* ` */ + 0x20,0x54,0x54,0x54,0x78, /* a */ + 0x7F,0x44,0x44,0x44,0x38, /* b */ + 0x38,0x44,0x44,0x44,0x44, /* c */ + 0x38,0x44,0x44,0x44,0x7f, /* d */ + 0x38,0x54,0x54,0x54,0x18, /* e */ + 0x04,0x04,0x7e,0x05,0x05, /* f */ + 0x08,0x54,0x54,0x54,0x3c, /* g */ + 0x7f,0x08,0x04,0x04,0x78, /* h */ + 0x00,0x44,0x7d,0x40,0x00, /* i */ + 0x20,0x40,0x44,0x3d,0x00, /* j */ + 0x7f,0x10,0x28,0x44,0x00, /* k */ + 0x00,0x41,0x7f,0x40,0x00, /* l */ + 0x7c,0x04,0x7c,0x04,0x78, /* m */ + 0x7c,0x08,0x04,0x04,0x78, /* n */ + 0x38,0x44,0x44,0x44,0x38, /* o */ + 0x7c,0x14,0x14,0x14,0x08, /* p */ + 0x08,0x14,0x14,0x14,0x7c, /* q */ + 0x7c,0x08,0x04,0x04,0x00, /* r */ + 0x48,0x54,0x54,0x54,0x24, /* s */ + 0x04,0x04,0x3f,0x44,0x44, /* t */ + 0x3c,0x40,0x40,0x20,0x7c, /* u */ + 0x1c,0x20,0x40,0x20,0x1c, /* v */ + 0x3c,0x40,0x30,0x40,0x3c, /* w */ + 0x44,0x28,0x10,0x28,0x44, /* x */ + 0x0c,0x50,0x50,0x50,0x3c, /* y */ + 0x44,0x64,0x54,0x4c,0x44, /* z */ + 0x08,0x36,0x41,0x41,0x00, /* { */ + 0x00,0x00,0x77,0x00,0x00, /* | */ + 0x00,0x41,0x41,0x36,0x08, /* } */ + 0x08,0x08,0x2a,0x1c,0x08, /* <- */ + 0x08,0x1c,0x2a,0x08,0x08, /* -> */ + 0xff,0xff,0xff,0xff,0xff, /*  */ +}; + +/* System 7x8 */ +const uint8_t au8FontSystem7x8[]= +{ + 0, 0, 0, 0, 0, 0, 0, //' ' + 0, 6, 95, 95, 6, 0, 0, //'!' + 0, 7, 7, 0, 7, 7, 0, //'"' + 20, 127, 127, 20, 127, 127, 20, //'#' + 36, 46, 107, 107, 58, 18, 0, //'$' + 70, 102, 48, 24, 12, 102, 98, //'%' + 48, 122, 79, 93, 55, 122, 72, //'&' + 4, 7, 3, 0, 0, 0, 0, //''' + 0, 28, 62, 99, 65, 0, 0, //'(' + 0, 65, 99, 62, 28, 0, 0, //')' + 8, 42, 62, 28, 28, 62, 42, //'*' + 8, 8, 62, 62, 8, 8, 0, //'+' + 0, 128, 224, 96, 0, 0, 0, //',' + 8, 8, 8, 8, 8, 8, 0, //'-' + 0, 0, 96, 96, 0, 0, 0, //'.' + 96, 48, 24, 12, 6, 3, 1, //'/' + 62, 127, 113, 89, 77, 127, 62, //'0' + 64, 66, 127, 127, 64, 64, 0, //'1' + 98, 115, 89, 73, 111, 102, 0, //'2' + 34, 99, 73, 73, 127, 54, 0, //'3' + 24, 28, 22, 83, 127, 127, 80, //'4' + 39, 103, 69, 69, 125, 57, 0, //'5' + 60, 126, 75, 73, 121, 48, 0, //'6' + 3, 3, 113, 121, 15, 7, 0, //'7' + 54, 127, 73, 73, 127, 54, 0, //'8' + 6, 79, 73, 105, 63, 30, 0, //'9' + 0, 0, 102, 102, 0, 0, 0, //':' + 0, 128, 230, 102, 0, 0, 0, //';' + 8, 28, 54, 99, 65, 0, 0, //'<' + 36, 36, 36, 36, 36, 36, 0, //'=' + 0, 65, 99, 54, 28, 8, 0, //'>' + 2, 3, 81, 89, 15, 6, 0, //'?' + 62, 127, 65, 93, 93, 31, 30, //'@' + 124,126, 19, 19, 126, 124, 0, //'A' + 65, 127, 127, 73, 73, 127, 54, //'B' + 28, 62, 99, 65, 65, 99, 34, //'C' + 65, 127, 127, 65, 99, 62, 28, //'D' + 65, 127, 127, 73, 93, 65, 99, //'E' + 65, 127, 127, 73, 29, 1, 3, //'F' + 28, 62, 99, 65, 81, 115, 114, //'G' + 127,127, 8, 8, 127, 127, 0, //'H' + 0, 65, 127, 127, 65, 0, 0, //'I' + 48, 112, 64, 65, 127, 63, 1, //'J' + 65, 127, 127, 8, 28, 119, 99, //'K' + 65, 127, 127, 65, 64, 96, 112, //'L' + 127,127, 14, 28, 14, 127, 127, //'M' + 127,127, 6, 12, 24, 127, 127, //'N' + 28, 62, 99, 65, 99, 62, 28, //'O' + 65, 127, 127, 73, 9, 15, 6, //'P' + 30, 63, 33, 113, 127, 94, 0, //'Q' + 65, 127, 127, 9, 25, 127, 102, //'R' + 38, 111, 77, 89, 115, 50, 0, //'S' + 3, 65, 127, 127, 65, 3, 0, //'T' + 127,127, 64, 64, 127, 127, 0, //'U' + 31, 63, 96, 96, 63, 31, 0, //'V' + 127,127, 48, 24, 48, 127, 127, //'W' + 67, 103, 60, 24, 60, 103, 67, //'X' + 7, 79, 120, 120, 79, 7, 0, //'Y' + 71, 99, 113, 89, 77, 103, 115, //'Z' + 0, 127, 127, 65, 65, 0, 0, //'[' + 1, 3, 6, 12, 24, 48, 96, //'\' + 0, 65, 65, 127, 127, 0, 0, //']' + 8, 12, 6, 3, 6, 12, 8, //'^' + 128,128, 128, 128, 128, 128, 128, //'_' + 0, 0, 3, 7, 4, 0, 0, //'`' + 32, 116, 84, 84, 60, 120, 64, //'a' + 65, 127, 63, 72, 72, 120, 48, //'b' + 56, 124, 68, 68, 108, 40, 0, //'c' + 48, 120, 72, 73, 63, 127, 64, //'d' + 56, 124, 84, 84, 92, 24, 0, //'e' + 72, 126, 127, 73, 3, 2, 0, //'f' + 56, 188, 164, 164, 252, 120, 0, //'g' + 65, 127, 127, 8, 4, 124, 120, //'h' + 0, 68, 125, 125, 64, 0, 0, //'i' + 96, 224, 128, 128, 253, 125, 0, //'j' + 65, 127, 127, 16, 56, 108, 68, //'k' + 0, 65, 127, 127, 64, 0, 0, //'l' + 120,124, 28, 56, 28, 124, 120, //'m' + 124,124, 4, 4, 124, 120, 0, //'n' + 56, 124, 68, 68, 124, 56, 0, //'o' + 0, 252, 252, 164, 36, 60, 24, //'p' + 24, 60, 36, 164, 248, 252, 132, //'q' + 68, 124, 120, 76, 4, 28, 24, //'r' + 72, 92, 84, 84, 116, 36, 0, //'s' + 0, 4, 62, 127, 68, 36, 0, //'t' + 60, 124, 64, 64, 60, 124, 64, //'u' + 28, 60, 96, 96, 60, 28, 0, //'v' + 60, 124, 112, 56, 112, 124, 60, //'w' + 68, 108, 56, 16, 56, 108, 68, //'x' + 60, 188, 160, 160, 252, 124, 0, //'y' + 76, 100, 116, 92, 76, 100, 0, //'z' + 8, 8, 62, 119, 65, 65, 0, //'{' + 0, 0, 0, 119, 119, 0, 0, //'|' + 65, 65, 119, 62, 8, 8, 0, //'}' + 2, 3, 1, 3, 2, 3, 1, //'~' + 255,129, 129, 129, 129, 129, 255, //'' + 14, 159, 145, 177, 251, 74, 0 //'Á' +}; + +/* 8x8 Normal */ +const uint8_t au8Font8x8[]= { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ASCII - 32 + 0x00,0x00,0x00,0x5F,0x5F,0x00,0x00,0x00, // ASCII - 33 + 0x00,0x00,0x03,0x07,0x00,0x07,0x03,0x00, // ASCII - 34 + 0x00,0x10,0x74,0x1C,0x77,0x1C,0x17,0x04, // ASCII - 35 + 0x00,0x24,0x2E,0x2A,0x7F,0x2A,0x3A,0x10, // ASCII - 36 + 0x00,0x4C,0x6A,0x76,0x1A,0x6A,0x56,0x33, // ASCII - 37 + 0x00,0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48, // ASCII - 38 + 0x00,0x00,0x04,0x07,0x03,0x00,0x00,0x00, // ASCII - 39 + 0x00,0x00,0x00,0x1C,0x3E,0x63,0x41,0x00, // ASCII - 40 + 0x00,0x00,0x41,0x63,0x3E,0x1C,0x00,0x00, // ASCII - 41 + 0x00,0x08,0x2A,0x3E,0x1C,0x3E,0x2A,0x08, // ASCII - 42 + 0x00,0x08,0x08,0x3E,0x3E,0x08,0x08,0x00, // ASCII - 43 + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // ASCII - 44 + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // ASCII - 45 + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // ASCII - 46 + 0x00,0x60,0x30,0x18,0x0C,0x06,0x03,0x01, // ASCII - 47 + 0x00,0x1C,0x3E,0x61,0x43,0x3E,0x1C,0x00, // ASCII - 48 + 0x00,0x00,0x44,0x7F,0x7F,0x40,0x00,0x00, // ASCII - 49 + 0x00,0x46,0x67,0x71,0x59,0x4F,0x66,0x00, // ASCII - 50 + 0x00,0x22,0x63,0x49,0x4D,0x7F,0x32,0x00, // ASCII - 51 + 0x00,0x18,0x1C,0x52,0x7F,0x7F,0x50,0x00, // ASCII - 52 + 0x00,0x2F,0x6F,0x45,0x45,0x7D,0x39,0x00, // ASCII - 53 + 0x00,0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00, // ASCII - 54 + 0x00,0x07,0x43,0x71,0x7D,0x0F,0x03,0x00, // ASCII - 55 + 0x00,0x36,0x7F,0x4D,0x59,0x7F,0x36,0x00, // ASCII - 56 + 0x00,0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00, // ASCII - 57 + 0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00, // ASCII - 58 + 0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00, // ASCII - 59 + 0x00,0x00,0x08,0x1C,0x36,0x63,0x41,0x00, // ASCII - 60 + 0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // ASCII - 61 + 0x00,0x00,0x41,0x63,0x36,0x1C,0x08,0x00, // ASCII - 62 + 0x00,0x02,0x07,0x51,0x59,0x0F,0x06,0x00, // ASCII - 63 + 0x00,0x3E,0x41,0x5D,0x55,0x5D,0x51,0x1E, // ASCII - 64 + 0x00,0x40,0x70,0x1D,0x17,0x1F,0x78,0x60, // ASCII - 65 + 0x00,0x41,0x7F,0x7F,0x49,0x4F,0x7E,0x30, // ASCII - 66 + 0x00,0x1C,0x3E,0x63,0x41,0x41,0x42,0x27, // ASCII - 67 + 0x00,0x41,0x7F,0x7F,0x41,0x63,0x3E,0x1C, // ASCII - 68 + 0x00,0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63, // ASCII - 69 + 0x00,0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03, // ASCII - 70 + 0x00,0x1C,0x3E,0x63,0x41,0x51,0x72,0x77, // ASCII - 71 + 0x00,0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00, // ASCII - 72 + 0x00,0x00,0x41,0x7F,0x7F,0x41,0x00,0x00, // ASCII - 73 + 0x00,0x30,0x70,0x41,0x41,0x7F,0x3F,0x01, // ASCII - 74 + 0x00,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x41, // ASCII - 75 + 0x00,0x41,0x7F,0x7F,0x41,0x40,0x60,0x70, // ASCII - 76 + 0x00,0x7F,0x7E,0x0C,0x18,0x0C,0x7E,0x7F, // ASCII - 77 + 0x00,0x7F,0x7E,0x0C,0x18,0x30,0x7F,0x7F, // ASCII - 78 + 0x00,0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C, // ASCII - 79 + 0x00,0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06, // ASCII - 80 + 0x00,0x1C,0x3E,0x63,0x51,0x63,0x3E,0x1C, // ASCII - 81 + 0x00,0x7F,0x7F,0x09,0x19,0x7F,0x66,0x40, // ASCII - 82 + 0x00,0x66,0x6F,0x4D,0x59,0x7B,0x33,0x00, // ASCII - 83 + 0x00,0x03,0x41,0x7F,0x7F,0x41,0x03,0x00, // ASCII - 84 + 0x00,0x3F,0x7F,0x40,0x40,0x40,0x7F,0x3F, // ASCII - 85 + 0x00,0x03,0x0F,0x3D,0x70,0x1D,0x07,0x01, // ASCII - 86 + 0x00,0x0F,0x7F,0x30,0x1C,0x30,0x7F,0x0F, // ASCII - 87 + 0x00,0x63,0x77,0x1C,0x1C,0x77,0x63,0x00, // ASCII - 88 + 0x01,0x03,0x47,0x7C,0x78,0x47,0x03,0x01, // ASCII - 89 + 0x00,0x67,0x73,0x59,0x4D,0x67,0x73,0x00, // ASCII - 90 + 0x00,0x00,0x00,0x7F,0x7F,0x41,0x41,0x00, // ASCII - 91 + 0x00,0x01,0x03,0x06,0x0C,0x18,0x30,0x60, // ASCII - 92 + 0x00,0x00,0x41,0x41,0x7F,0x7F,0x00,0x00, // ASCII - 93 + 0x00,0x00,0x04,0x06,0x03,0x06,0x04,0x00, // ASCII - 94 + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ASCII - 95 + 0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // ASCII - 96 + 0x00,0x68,0x6C,0x54,0x54,0x3C,0x78,0x40, // ASCII - 97 + 0x00,0x41,0x7F,0x3F,0x6C,0x44,0x7C,0x38, // ASCII - 98 + 0x00,0x38,0x7C,0x44,0x44,0x6C,0x2C,0x00, // ASCII - 99 + 0x00,0x38,0x7C,0x44,0x49,0x3F,0x7F,0x40, // ASCII - 100 + 0x00,0x38,0x7C,0x54,0x54,0x5C,0x58,0x00, // ASCII - 101 + 0x00,0x00,0x48,0x7E,0x7F,0x49,0x0B,0x02, // ASCII - 102 + 0x00,0x48,0x7C,0x34,0x34,0x2C,0x68,0x44, // ASCII - 103 + 0x00,0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78, // ASCII - 104 + 0x00,0x00,0x44,0x7D,0x7D,0x40,0x00,0x00, // ASCII - 105 + 0x00,0x60,0x60,0x04,0x7D,0x7D,0x00,0x00, // ASCII - 106 + 0x00,0x41,0x7F,0x7F,0x10,0x78,0x6C,0x44, // ASCII - 107 + 0x00,0x00,0x41,0x7F,0x7F,0x40,0x00,0x00, // ASCII - 108 + 0x00,0x7C,0x7C,0x0C,0x78,0x0C,0x7C,0x78, // ASCII - 109 + 0x00,0x44,0x7C,0x7C,0x08,0x04,0x7C,0x78, // ASCII - 110 + 0x00,0x38,0x7C,0x44,0x44,0x7C,0x38,0x00, // ASCII - 111 + 0x00,0x04,0x7C,0x78,0x24,0x24,0x3C,0x18, // ASCII - 112 + 0x00,0x18,0x3C,0x24,0x24,0x78,0x7C,0x00, // ASCII - 113 + 0x00,0x44,0x7C,0x78,0x4C,0x04,0x1C,0x18, // ASCII - 114 + 0x00,0x48,0x5C,0x5C,0x74,0x74,0x24,0x00, // ASCII - 115 + 0x00,0x00,0x04,0x3E,0x7F,0x44,0x24,0x00, // ASCII - 116 + 0x00,0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40, // ASCII - 117 + 0x00,0x04,0x1C,0x3C,0x60,0x30,0x1C,0x04, // ASCII - 118 + 0x00,0x1C,0x7C,0x30,0x1C,0x30,0x7C,0x1C, // ASCII - 119 + 0x00,0x44,0x6C,0x3C,0x10,0x78,0x6C,0x44, // ASCII - 120 + 0x00,0x44,0x4C,0x1C,0x70,0x64,0x1C,0x0C, // ASCII - 121 + 0x00,0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00, // ASCII - 122 + 0x00,0x08,0x08,0x3E,0x77,0x41,0x41,0x00, // ASCII - 123 + 0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00, // ASCII - 124 + 0x00,0x41,0x41,0x77,0x3E,0x08,0x08,0x00, // ASCII - 125 + 0x00,0x02,0x01,0x01,0x03,0x02,0x02,0x01, // ASCII - 126 + 0x00,0x60,0x78,0x4E,0x47,0x5E,0x78,0x60, // ASCII - 127 + 0x00,0x1C,0x3E,0x23,0x41,0x41,0x42,0x27, // ASCII - 128 + 0x00,0x3D,0x7D,0x40,0x41,0x3D,0x7C,0x40, // ASCII - 129 +}; + +/* 8x8 Thin */ +const uint8_t au8Font8x8Thin[]= { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00, + 0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, + 0x00,0x14,0x7F,0x14,0x14,0x7F,0x14,0x00, + 0x00,0x24,0x2A,0x6B,0x6B,0x2A,0x12,0x00, + 0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00, + 0x30,0x4A,0x45,0x4D,0x32,0x48,0x48,0x00, + 0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00, + 0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00, + 0x00,0x00,0x41,0x22,0x1C,0x00,0x00,0x00, + 0x08,0x2A,0x1C,0x1C,0x1C,0x2A,0x08,0x00, + 0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00, + 0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00, + 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, + 0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00, + 0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x00, + 0x00,0x3E,0x61,0x51,0x49,0x45,0x3E,0x00, + 0x00,0x44,0x42,0x7F,0x40,0x40,0x00,0x00, + 0x00,0x62,0x51,0x51,0x49,0x49,0x66,0x00, + 0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00, + 0x10,0x18,0x14,0x52,0x7F,0x50,0x10,0x00, + 0x00,0x27,0x45,0x45,0x45,0x45,0x39,0x00, + 0x00,0x3C,0x4A,0x49,0x49,0x49,0x30,0x00, + 0x00,0x03,0x01,0x71,0x09,0x05,0x03,0x00, + 0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00, + 0x00,0x06,0x49,0x49,0x49,0x29,0x1E,0x00, + 0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x66,0x00,0x00,0x00,0x00, + 0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00, + 0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00, + 0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00, + 0x00,0x02,0x01,0x01,0x51,0x09,0x06,0x00, + 0x00,0x3E,0x41,0x5D,0x55,0x55,0x1E,0x00, + 0x00,0x7C,0x12,0x11,0x11,0x12,0x7C,0x00, + 0x00,0x41,0x7F,0x49,0x49,0x49,0x36,0x00, + 0x00,0x1C,0x22,0x41,0x41,0x41,0x22,0x00, + 0x00,0x41,0x7F,0x41,0x41,0x22,0x1C,0x00, + 0x00,0x41,0x7F,0x49,0x5D,0x41,0x63,0x00, + 0x00,0x41,0x7F,0x49,0x1D,0x01,0x03,0x00, + 0x00,0x1C,0x22,0x41,0x51,0x51,0x72,0x00, + 0x00,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00, + 0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x00, + 0x00,0x30,0x40,0x40,0x41,0x3F,0x01,0x00, + 0x00,0x41,0x7F,0x08,0x14,0x22,0x41,0x40, + 0x00,0x41,0x7F,0x41,0x40,0x40,0x60,0x00, + 0x00,0x7F,0x01,0x02,0x04,0x02,0x01,0x7F, + 0x00,0x7F,0x01,0x02,0x04,0x08,0x7F,0x00, + 0x00,0x3E,0x41,0x41,0x41,0x41,0x3E,0x00, + 0x00,0x41,0x7F,0x49,0x09,0x09,0x06,0x00, + 0x00,0x1E,0x21,0x21,0x31,0x21,0x5E,0x40, + 0x00,0x41,0x7F,0x49,0x19,0x29,0x46,0x00, + 0x00,0x26,0x49,0x49,0x49,0x49,0x32,0x00, + 0x00,0x03,0x01,0x41,0x7F,0x41,0x01,0x03, + 0x00,0x3F,0x40,0x40,0x40,0x40,0x3F,0x00, + 0x00,0x0F,0x10,0x20,0x40,0x20,0x10,0x0F, + 0x00,0x3F,0x40,0x40,0x38,0x40,0x40,0x3F, + 0x00,0x41,0x22,0x14,0x08,0x14,0x22,0x41, + 0x00,0x01,0x02,0x44,0x78,0x44,0x02,0x01, + 0x00,0x43,0x61,0x51,0x49,0x45,0x43,0x61, + 0x00,0x7F,0x41,0x41,0x41,0x00,0x00,0x00, + 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00, + 0x00,0x41,0x41,0x41,0x7F,0x00,0x00,0x00, + 0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00, + 0x00,0x20,0x54,0x54,0x54,0x54,0x78,0x40, + 0x00,0x01,0x7F,0x30,0x48,0x48,0x48,0x30, + 0x00,0x38,0x44,0x44,0x44,0x44,0x28,0x00, + 0x00,0x30,0x48,0x48,0x48,0x31,0x7F,0x40, + 0x00,0x38,0x54,0x54,0x54,0x54,0x18,0x00, + 0x00,0x00,0x48,0x7E,0x49,0x01,0x02,0x00, + 0x00,0x98,0xA4,0xA4,0xA4,0xA4,0x78,0x04, + 0x00,0x41,0x7F,0x08,0x04,0x04,0x78,0x00, + 0x00,0x00,0x44,0x7D,0x40,0x00,0x00,0x00, + 0x00,0x60,0x80,0x80,0x80,0x84,0x7D,0x00, + 0x00,0x01,0x7F,0x10,0x28,0x44,0x40,0x00, + 0x00,0x00,0x41,0x7F,0x40,0x00,0x00,0x00, + 0x00,0x7C,0x04,0x04,0x78,0x04,0x04,0x78, + 0x00,0x7C,0x08,0x04,0x04,0x04,0x78,0x00, + 0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00, + 0x00,0x84,0xFC,0x98,0x24,0x24,0x18,0x00, + 0x00,0x18,0x24,0x24,0x98,0xFC,0x84,0x00, + 0x00,0x44,0x7C,0x48,0x04,0x04,0x18,0x00, + 0x00,0x48,0x54,0x54,0x54,0x54,0x24,0x00, + 0x00,0x04,0x04,0x3F,0x44,0x44,0x20,0x00, + 0x00,0x3C,0x40,0x40,0x40,0x20,0x7C,0x00, + 0x00,0x0C,0x10,0x20,0x40,0x20,0x10,0x0C, + 0x00,0x3C,0x40,0x40,0x38,0x40,0x40,0x3C, + 0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00, + 0x00,0x9C,0xA0,0xA0,0xA0,0xA0,0x7C,0x00, + 0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00, + 0x00,0x08,0x08,0x36,0x41,0x41,0x00,0x00, + 0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00, + 0x00,0x00,0x41,0x41,0x36,0x08,0x08,0x00, + 0x00,0x02,0x01,0x01,0x02,0x02,0x01,0x00, + 0x00,0x70,0x48,0x44,0x42,0x44,0x48,0x70, + 0x00,0x0E,0x91,0x91,0xB1,0xB1,0x4A,0x00, + 0x00,0x3A,0x40,0x40,0x40,0x7A,0x40,0x00, + 0x00,0x38,0x54,0x54,0x55,0x55,0x18,0x00, + 0x00,0x22,0x55,0x55,0x55,0x79,0x42,0x00, + 0x00,0x21,0x54,0x54,0x54,0x78,0x41,0x00, + 0x00,0x20,0x55,0x55,0x54,0x78,0x40,0x00, + 0x00,0x20,0x54,0x55,0x54,0x78,0x40,0x00, + 0x00,0x18,0x24,0xA4,0xA4,0xE4,0x40,0x00, + 0x00,0x3A,0x55,0x55,0x55,0x55,0x1A,0x00, + 0x00,0x39,0x54,0x54,0x54,0x54,0x19,0x00, + 0x00,0x38,0x55,0x55,0x54,0x54,0x18,0x00, + 0x00,0x00,0x01,0x44,0x7C,0x41,0x00,0x00, + 0x02,0x01,0x45,0x7D,0x41,0x01,0x02,0x00, + 0x00,0x00,0x01,0x45,0x7C,0x40,0x00,0x00, + 0x00,0x79,0x14,0x12,0x12,0x14,0x79,0x00, + 0x00,0x70,0x28,0x2B,0x2B,0x28,0x70,0x00, + 0x00,0x44,0x7C,0x54,0x55,0x45,0x00,0x00, + 0x00,0x20,0x54,0x54,0x58,0x38,0x54,0x54, + 0x00,0x7C,0x0A,0x09,0x09,0x7F,0x49,0x49, + 0x00,0x30,0x4A,0x49,0x49,0x4A,0x30,0x00, + 0x00,0x32,0x48,0x48,0x48,0x48,0x32,0x00, + 0x00,0x30,0x49,0x4A,0x48,0x48,0x30,0x00, + 0x00,0x38,0x42,0x41,0x41,0x42,0x38,0x00, + 0x00,0x38,0x41,0x42,0x40,0x40,0x38,0x00, + 0x00,0x1A,0xA0,0xA0,0xA0,0xA0,0x7A,0x00, + 0x00,0x19,0x24,0x42,0x42,0x24,0x19,0x00, + 0x00,0x3D,0x40,0x40,0x40,0x40,0x3D,0x00, + 0x00,0x18,0x24,0x24,0xE7,0x24,0x24,0x00, + 0x00,0x68,0x5E,0x49,0x41,0x42,0x20,0x00, + 0x00,0x15,0x16,0x7C,0x16,0x15,0x00,0x00, + 0x81,0xFF,0x85,0x05,0x17,0xFA,0x90,0x50, + 0x40,0x88,0x88,0x7F,0x09,0x09,0x02,0x00, + 0x00,0x20,0x54,0x54,0x55,0x79,0x40,0x00, +}; diff --git a/drivers/lcd/smallfonts.h b/drivers/lcd/smallfonts.h new file mode 100644 index 0000000..e0c2a9f --- /dev/null +++ b/drivers/lcd/smallfonts.h @@ -0,0 +1,68 @@ +/**************************************************************************/ +/*! + @file smallfonts.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __SMALLFONTS_H_ +#define __SMALLFONTS_H_ + +/* Partially based on original code for the KS0108 by Stephane Rey */ +/* Current version by Kevin Townsend */ +/* Last Updated: 12 May 2009 */ + +#include "projectconfig.h" + +struct FONT_DEF +{ + uint8_t u8Width; /* Character width for storage */ + uint8_t u8Height; /* Character height for storage */ + uint8_t u8FirstChar; /* The first character available */ + uint8_t u8LastChar; /* The last character available */ + const uint8_t *au8FontTable; /* Font table start address in memory */ +}; + +extern const struct FONT_DEF Font_System3x6; +extern const struct FONT_DEF Font_System5x8; +extern const struct FONT_DEF Font_System7x8; +extern const struct FONT_DEF Font_8x8; +extern const struct FONT_DEF Font_8x8Thin; + +extern const uint8_t au8FontSystem3x6[]; +extern const uint8_t au8FontSystem5x8[]; +extern const uint8_t au8FontSystem7x8[]; +extern const uint8_t au8Font8x8[]; +extern const uint8_t au8Font8x8Thin[]; + +#endif diff --git a/drivers/lcd/tft/bmp.c b/drivers/lcd/tft/bmp.c new file mode 100644 index 0000000..60d1ebf --- /dev/null +++ b/drivers/lcd/tft/bmp.c @@ -0,0 +1,351 @@ +/**************************************************************************/ +/*! + @file bmp.c + @author K. Townsend (microBuilder.eu) + + @brief Loads uncomprssed 24-bit windows bitmaps images + + Based on the information available at: + http://local.wasp.uwa.edu.au/~pbourke/dataformats/bmp/ + and some sample code written by Michael Sweet + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "bmp.h" + +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/lcd.h" + +// Only include read support if CFG_SDCARD is defined +#ifdef CFG_SDCARD + #include "drivers/fatfs/diskio.h" + #include "drivers/fatfs/ff.h" + static FATFS Fatfs[1]; + #if defined CFG_SDCARD_READONLY && CFG_SDCARD_READONLY == 0 + static FILINFO Finfo; + static FIL bmpSDFile; + #endif + +/**************************************************************************/ +/* */ +/* ----------------------- Private Methods ------------------------------ */ +/* */ +/**************************************************************************/ +bmp_error_t bmpParseBitmap(uint16_t x, uint16_t y, FIL file) +{ + UINT bytesRead; + bmp_header_t header; + bmp_infoheader_t infoHeader; + + // Read the file header + // ToDo: Optimise this to read buffer once and parse it + f_read(&file, &header.type, sizeof(header.type), &bytesRead); + f_read(&file, &header.size, sizeof(header.size), &bytesRead); + f_read(&file, &header.reserved1, sizeof(header.reserved1), &bytesRead); + f_read(&file, &header.reserved2, sizeof(header.reserved2), &bytesRead); + f_read(&file, &header.offset, sizeof(header.offset), &bytesRead); + + // Make sure this is a bitmap (first two bytes = 'BM' or 0x4D42 on little-endian systems) + if (header.type != 0x4D42) return BMP_ERROR_NOTABITMAP; + + // Read the info header + // ToDo: Optimise this to read buffer once and parse it + f_read(&file, &infoHeader.size, sizeof(infoHeader.size), &bytesRead); + f_read(&file, &infoHeader.width, sizeof(infoHeader.width), &bytesRead); + f_read(&file, &infoHeader.height, sizeof(infoHeader.height), &bytesRead); + f_read(&file, &infoHeader.planes, sizeof(infoHeader.planes), &bytesRead); + f_read(&file, &infoHeader.bits, sizeof(infoHeader.bits), &bytesRead); + f_read(&file, &infoHeader.compression, sizeof(infoHeader.compression), &bytesRead); + f_read(&file, &infoHeader.imagesize, sizeof(infoHeader.imagesize), &bytesRead); + f_read(&file, &infoHeader.xresolution, sizeof(infoHeader.xresolution), &bytesRead); + f_read(&file, &infoHeader.yresolution, sizeof(infoHeader.yresolution), &bytesRead); + f_read(&file, &infoHeader.ncolours, sizeof(infoHeader.ncolours), &bytesRead); + f_read(&file, &infoHeader.importantcolours, sizeof(infoHeader.importantcolours), &bytesRead); + + // Make sure that this is a 24-bit image + if (infoHeader.bits != 24) + return BMP_ERROR_INVALIDBITDEPTH; + + // Check image dimensions + if ((infoHeader.width > lcdGetWidth()) | (infoHeader.height > lcdGetHeight())) + return BMP_ERROR_INVALIDDIMENSIONS; + + // Make sure image is not compressed + if (infoHeader.compression != BMP_COMPRESSION_NONE) + return BMP_ERROR_COMPRESSEDDATA; + + // Read 24-bit image data + uint32_t px, py; + FRESULT res; + uint8_t buffer[infoHeader.width * 3]; + for (py = infoHeader.height; py > 0; py--) + { + // Read one row at a time + res = f_read(&file, &buffer, infoHeader.width * 3, &bytesRead); + if (res || bytesRead == 0) + { + // Error or EOF + return BMP_ERROR_PREMATUREEOF; + } + for (px = 0; px < infoHeader.width; px++) + { + // Render pixel + // ToDo: This is a brutally slow way of rendering bitmaps ... + // update to pass one row of data at a time + drawPixel(x + px, y + py - 1, drawRGB24toRGB565(buffer[(px * 3) + 2], buffer[(px * 3) + 1], buffer[(px * 3)])); + } + } + + return BMP_ERROR_NONE; +} + +/**************************************************************************/ +/* */ +/* ----------------------- Public Methods ------------------------------- */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Loads a 24-bit Windows bitmap image from an SD card and + renders it + + @section Example + + @code + + #include "drivers/lcd/tft/bmp.h" + + bmp_error_t error; + + // Draw image.bmp (from the root folder) starting at pixel 0,0 + error = bmpDrawBitmap(0, 0, "/image.bmp"); + + // Check 'error' for problems such as BMP_ERROR_FILENOTFOUND + + @endcode +*/ +/**************************************************************************/ +bmp_error_t bmpDrawBitmap(uint16_t x, uint16_t y, const char* filename) +{ + bmp_error_t error = BMP_ERROR_NONE; + DSTATUS stat; + BYTE res; + + stat = disk_initialize(0); + + if ((stat & STA_NOINIT) || (stat & STA_NODISK)) + { + // Card not initialised or no disk present + return BMP_ERROR_SDINITFAIL; + } + + if (stat == 0) + { + // Try to mount drive + res = f_mount(0, &Fatfs[0]); + if (res != FR_OK) + { + // Failed to mount 0: + return BMP_ERROR_SDINITFAIL; + } + if (res == FR_OK) + { + // Try to open the requested file + FIL imgfile; + if(f_open(&imgfile, filename, FA_READ | FA_OPEN_EXISTING) != FR_OK) + { + // Unable to open the requested file + return BMP_ERROR_FILENOTFOUND; + } + // Try to render the specified image + error = bmpParseBitmap(x, y, imgfile); + // Close file + f_close(&imgfile); + // Unmount drive + f_mount(0,0); + // Return results + return error; + } + } + + // Return OK signal + return BMP_ERROR_NONE; +} + +#if defined CFG_SDCARD_READONLY && CFG_SDCARD_READONLY == 0 +/**************************************************************************/ +/*! + @brief Writes the contents of the LCD screen to a 24-bit bitmap + images. CFG_SDCARD_READONLY must be set to '0' to be able + to use this function. + + @section Example + + @code + + #include "drivers/lcd/tft/bmp.h" + + bmp_error_t error; + + // Note: The LED stays on while the image is being written since + // it can take quite a while to read the entire screen + // pixel by pixel and write the data to the SD card + + // Turn the LED on to signal busy state + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + // Write the screen contents to a bitmap image + error = bmpSaveScreenshot("capture.bmp"); + // Turn the LED off to indicate that the capture is complete + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + + // Check 'error' for problems + + @endcode +*/ +/**************************************************************************/ +bmp_error_t bmpSaveScreenshot(const char* filename) +{ + DSTATUS stat; + bmp_error_t error = BMP_ERROR_NONE; + bmp_header_t header; + bmp_infoheader_t infoHeader; + uint32_t lcdWidth, lcdHeight, x, y, bgra32; + UINT bytesWritten; + uint16_t rgb565, eof; + uint8_t r, g, b; + + // Create a new file (Crossworks only) + stat = disk_initialize(0); + if (stat & STA_NOINIT) + { + return BMP_ERROR_SDINITFAIL; + } + if (stat & STA_NODISK) + { + return BMP_ERROR_SDINITFAIL; + } + if (stat == 0) + { + // SD card sucessfully initialised + DSTATUS stat; + DWORD p2; + WORD w1; + BYTE res, b1; + DIR dir; + // Try to mount drive + res = f_mount(0, &Fatfs[0]); + if (res != FR_OK) + { + return BMP_ERROR_SDINITFAIL; + } + if (res == FR_OK) + { + // Create a file (overwriting any existing file!) + if(f_open(&bmpSDFile, filename, FA_READ | FA_WRITE | FA_CREATE_ALWAYS)!=FR_OK) + { + return BMP_ERROR_UNABLETOCREATEFILE; + } + } + } + + lcdWidth = lcdGetWidth(); + lcdHeight = lcdGetHeight(); + + // Create header + header.type = 0x4d42; // 'BM' + header.size = (lcdWidth * lcdHeight * 3) + sizeof(header) + sizeof(infoHeader); // File size in bytes + header.reserved1 = 0; + header.reserved2 = 0; + header.offset = 0x36; // Offset in bytes to the image data + + // Create infoheader + infoHeader.size = sizeof(infoHeader); + infoHeader.width = lcdWidth; + infoHeader.height = lcdHeight; + infoHeader.planes = 1; + infoHeader.bits = 24; + infoHeader.compression = BMP_COMPRESSION_NONE; + infoHeader.imagesize = (lcdWidth * lcdHeight * 3) + 2; // 3 bytes per pixel + 2 bytes for EOF + infoHeader.xresolution = 0x0B12; + infoHeader.yresolution = 0x0B12; + infoHeader.ncolours = 0; + infoHeader.importantcolours = 0; + + // Write header to disk + f_write(&bmpSDFile, &header.type, sizeof(header.type), &bytesWritten); + f_write(&bmpSDFile, &header.size, sizeof(header.size), &bytesWritten); + f_write(&bmpSDFile, &header.reserved1, sizeof(header.reserved1), &bytesWritten); + f_write(&bmpSDFile, &header.reserved2, sizeof(header.reserved2), &bytesWritten); + f_write(&bmpSDFile, &header.offset, sizeof(header.offset), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.size, sizeof(infoHeader.size), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.width, sizeof(infoHeader.width), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.height, sizeof(infoHeader.height), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.planes, sizeof(infoHeader.planes), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.bits, sizeof(infoHeader.bits), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.compression, sizeof(infoHeader.compression), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.imagesize, sizeof(infoHeader.imagesize), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.xresolution, sizeof(infoHeader.xresolution), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.yresolution, sizeof(infoHeader.yresolution), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.ncolours, sizeof(infoHeader.ncolours), &bytesWritten); + f_write(&bmpSDFile, &infoHeader.importantcolours, sizeof(infoHeader.importantcolours), &bytesWritten); + + // Write image data to disk (starting from bottom row) + for (y = lcdHeight; y != 0; y--) + { + for (x = 0; x < lcdWidth; x++) + { + rgb565 = lcdGetPixel(x, y - 1); // Get RGB565 pixel + bgra32 = drawRGB565toBGRA32(rgb565); // Convert RGB565 to 24-bit color + r = (bgra32 & 0x00FF0000) >> 16; + g = (bgra32 & 0x0000FF00) >> 8; + b = (bgra32 & 0x000000FF); + f_write(&bmpSDFile, &b, 1, &bytesWritten); // Write RGB data + f_write(&bmpSDFile, &g, 1, &bytesWritten); + f_write(&bmpSDFile, &r, 1, &bytesWritten); + } + } + + // Write EOF (2 bytes) + eof = 0x0000; + f_write(&bmpSDFile, &eof, 2, &bytesWritten); + + // Close the file + f_close(&bmpSDFile); + + // Return OK signal + return BMP_ERROR_NONE; +} +#endif // End of read-only check to write bitmaps + +#endif // End of CFG_SDCARD check diff --git a/drivers/lcd/tft/bmp.h b/drivers/lcd/tft/bmp.h new file mode 100644 index 0000000..f734047 --- /dev/null +++ b/drivers/lcd/tft/bmp.h @@ -0,0 +1,150 @@ +/**************************************************************************/ +/*! + @file bmp.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __BMP_H__ +#define __BMP_H__ + +#include "projectconfig.h" + +/************************************************************************** + Windows Bitmap File Format + ----------------------------------------------------------------------- + Windows bitmap images are relatively easy to work with because the + format is basic and requires limited overhead to work with (in + practice, image data is very rarely compressed). Bitmap files have + the following structure: + + -------------------------- + | Header | 14 bytes + |------------------------- + | Info Header | 40 bytes + ----------------------- + | Palette (optional) | + |------------------------- + | Image Data | + -------------------------- + + For more information on the bitmap file format, see: + http://local.wasp.uwa.edu.au/~pbourke/dataformats/bmp/ + + **************************************************************************/ + + +/**************************************************************************/ +/*! + @brief 14-byte Windows bitmap header +*/ +/**************************************************************************/ +typedef struct +{ + uint16_t type; /* Magic identifier */ + uint32_t size; /* File size in bytes */ + uint16_t reserved1; + uint16_t reserved2; + uint32_t offset; /* Offset to image data, bytes */ +} bmp_header_t; + +/**************************************************************************/ +/*! + @brief 40-byte Windows bitmap info header +*/ +/**************************************************************************/ +typedef struct +{ + uint32_t size; /* Header size in bytes */ + int32_t width; /* Width of the image */ + int32_t height; /* Height of image */ + uint16_t planes; /* Number of colour planes */ + uint16_t bits; /* Bits per pixel */ + uint32_t compression; /* Compression type */ + uint32_t imagesize; /* Image size in bytes */ + int32_t xresolution; /* Pixels per meter */ + int32_t yresolution; /* Pixels per meter */ + uint32_t ncolours; /* Number of colours */ + uint32_t importantcolours; /* Important colours */ +} bmp_infoheader_t; + +/**************************************************************************/ +/*! + @brief Describes the different compression methods available in + Windows bitmap images, though compression is not currently + supported by this code. +*/ +/**************************************************************************/ +typedef enum +{ + BMP_COMPRESSION_NONE = 0, + BMP_COMPRESSION_RLE8 = 1, + BMP_COMPRESSION_RLE4 = 2, + BMP_COMPRESSION_RGBMASK = 3 +} bmp_compression_t; + +/**************************************************************************/ +/*! + @brief 24-bit pixel data +*/ +/**************************************************************************/ +typedef struct +{ + uint8_t rgbBlue; /* Blue value */ + uint8_t rgbGreen; /* Green value */ + uint8_t rgbRed; /* Red value */ +} bmp_rgbdata_t; + +/**************************************************************************/ +/*! + @brief Error return codes when processing bitmap images +*/ +/**************************************************************************/ +typedef enum +{ + BMP_ERROR_NONE = 0, + BMP_ERROR_SDINITFAIL = 1, + BMP_ERROR_FILENOTFOUND = 2, + BMP_ERROR_UNABLETOCREATEFILE = 3, + BMP_ERROR_NOTABITMAP = 10, /* First two bytes of the image not 'BM' */ + BMP_ERROR_INVALIDBITDEPTH = 11, /* Image is not 24-bits */ + BMP_ERROR_COMPRESSEDDATA = 12, /* Image contains compressed data (not supported) */ + BMP_ERROR_INVALIDDIMENSIONS = 13, /* Image is > CFG_TFTLCD_WIDTH pixels wide or > CFG_TFTLCD_HEIGHT pixels high */ + BMP_ERROR_PREMATUREEOF = 14 /* EOF reached unexpectedly in pixel data */ +} bmp_error_t; + +bmp_error_t bmpDrawBitmap(uint16_t x, uint16_t y, const char* filename); + +#if defined CFG_SDCARD_READONLY && CFG_SDCARD_READONLY == 0 +bmp_error_t bmpSaveScreenshot(const char* filename); +#endif + +#endif diff --git a/drivers/lcd/tft/colors.h b/drivers/lcd/tft/colors.h new file mode 100644 index 0000000..eb39265 --- /dev/null +++ b/drivers/lcd/tft/colors.h @@ -0,0 +1,94 @@ +/**************************************************************************/ +/*! + @file colors.h + @author K. Townsend (microBuilder.eu) + + @brief Common 16-bit RGB565 color definitions + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __COLORS_H__ +#define __COLORS_H__ + +#include "projectconfig.h" + +// Basic Color definitions +#define COLOR_BLACK (uint16_t)(0x0000) +#define COLOR_BLUE (uint16_t)(0x001F) +#define COLOR_RED (uint16_t)(0xF800) +#define COLOR_GREEN (uint16_t)(0x07E0) +#define COLOR_CYAN (uint16_t)(0x07FF) +#define COLOR_MAGENTA (uint16_t)(0xF81F) +#define COLOR_YELLOW (uint16_t)(0xFFE0) +#define COLOR_WHITE (uint16_t)(0xFFFF) + +// Grayscale Values +#define COLOR_GRAY_15 (uint16_t)(0x0861) // 15 15 15 +#define COLOR_GRAY_30 (uint16_t)(0x18E3) // 30 30 30 +#define COLOR_GRAY_50 (uint16_t)(0x3186) // 50 50 50 +#define COLOR_GRAY_80 (uint16_t)(0x528A) // 80 80 80 +#define COLOR_GRAY_128 (uint16_t)(0x8410) // 128 128 128 +#define COLOR_GRAY_200 (uint16_t)(0xCE59) // 200 200 200 +#define COLOR_GRAY_225 (uint16_t)(0xE71C) // 225 225 225 + +// Color Palettes +#define COLOR_THEME_LIMEGREEN_BASE (uint16_t)(0xD7F0) // 211 255 130 +#define COLOR_THEME_LIMEGREEN_DARKER (uint16_t)(0x8DE8) // 137 188 69 +#define COLOR_THEME_LIMEGREEN_LIGHTER (uint16_t)(0xEFF9) // 238 255 207 +#define COLOR_THEME_LIMEGREEN_SHADOW (uint16_t)(0x73EC) // 119 127 103 +#define COLOR_THEME_LIMEGREEN_ACCENT (uint16_t)(0xAE6D) // 169 204 104 + +#define COLOR_THEME_VIOLET_BASE (uint16_t)(0x8AEF) // 143 94 124 +#define COLOR_THEME_VIOLET_DARKER (uint16_t)(0x4187) // 66 49 59 +#define COLOR_THEME_VIOLET_LIGHTER (uint16_t)(0xC475) // 194 142 174 +#define COLOR_THEME_VIOLET_SHADOW (uint16_t)(0x40E6) // 66 29 52 +#define COLOR_THEME_VIOLET_ACCENT (uint16_t)(0xC992) // 204 50 144 + +#define COLOR_THEME_EARTHY_BASE (uint16_t)(0x6269) // 97 79 73 +#define COLOR_THEME_EARTHY_DARKER (uint16_t)(0x3103) // 48 35 31 +#define COLOR_THEME_EARTHY_LIGHTER (uint16_t)(0x8C30) // 140 135 129 +#define COLOR_THEME_EARTHY_SHADOW (uint16_t)(0xAB29) // 173 102 79 +#define COLOR_THEME_EARTHY_ACCENT (uint16_t)(0xFE77) // 250 204 188 + +#define COLOR_THEME_SKYBLUE_BASE (uint16_t)(0x95BF) // 150 180 255 +#define COLOR_THEME_SKYBLUE_DARKER (uint16_t)(0x73B0) // 113 118 131 +#define COLOR_THEME_SKYBLUE_LIGHTER (uint16_t)(0xE75F) // 227 235 255 +#define COLOR_THEME_SKYBLUE_SHADOW (uint16_t)(0x4ACF) // 75 90 127 +#define COLOR_THEME_SKYBLUE_ACCENT (uint16_t)(0xB5F9) // 182 188 204 + +// Using these values allows you to update the entire UI color scheme in one location +#define COLOR_THEME_DEFAULT_BASE COLOR_THEME_LIMEGREEN_BASE +#define COLOR_THEME_DEFAULT_DARKER COLOR_THEME_LIMEGREEN_DARKER +#define COLOR_THEME_DEFAULT_LIGHTER COLOR_THEME_LIMEGREEN_LIGHTER +#define COLOR_THEME_DEFAULT_SHADOW COLOR_THEME_LIMEGREEN_SHADOW +#define COLOR_THEME_DEFAULT_ACCENT COLOR_THEME_LIMEGREEN_ACCENT + +#endif diff --git a/drivers/lcd/tft/dialogues/alphanumeric.c b/drivers/lcd/tft/dialogues/alphanumeric.c new file mode 100644 index 0000000..db22c32 --- /dev/null +++ b/drivers/lcd/tft/dialogues/alphanumeric.c @@ -0,0 +1,364 @@ +/**************************************************************************/ +/*! + @file alphanumeric.c + @author K. Townsend (microBuilder.eu) + + @brief Shows an alpha-numeric input dialogue + + @section Example + + @code + #include "drivers/lcd/tft/dialogues/alphanumeric.h" + + // Print results from an alpha-numeric dialogue + char* results = alphaShowDialogue(); + printf("%s\r\n", results); + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "alphanumeric.h" + +#include "core/systick/systick.h" +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/touchscreen.h" +#include "drivers/lcd/tft/fonts/dejavusans9.h" + +// Background and text input region colors +#define ALPHA_COLOR_BACKGROUND COLOR_GRAY_15 +#define ALPHA_COLOR_INPUTFILL COLOR_GRAY_30 +#define ALPHA_COLOR_INPUTTEXT COLOR_WHITE +// Button colors +#define ALPHA_COLOR_BTN_BORDER COLOR_GRAY_30 +#define ALPHA_COLOR_BTN_FILL COLOR_GRAY_30 +#define ALPHA_COLOR_BTN_FONT COLOR_WHITE +// Active button colors +#define ALPHA_COLOR_BTNEN_BORDER COLOR_THEME_DEFAULT_DARKER +#define ALPHA_COLOR_BTNEN_FILL COLOR_THEME_DEFAULT_BASE +#define ALPHA_COLOR_BTNEN_FONT COLOR_BLACK + +/* This kind of messes with your head, but defining the pixel locations + this way allows the calculator example to be rendered on another + TFT LCD with a different screen resolution or orientation without + having to rewrite all the individual pixel-level code */ + +#define ALPHA_BTN_SPACING (5) +#define ALPHA_BTN_WIDTH ((lcdGetWidth() - (ALPHA_BTN_SPACING * 6)) / 5) +#define ALPHA_KEYPAD_TOP ((lcdGetHeight() / 7) + (ALPHA_BTN_SPACING * 2)) +#define ALPHA_BTN_HEIGHT (((lcdGetHeight() - ALPHA_KEYPAD_TOP) - (ALPHA_BTN_SPACING * 7)) / 6) +// #define ALPHA_BTN_WIDTH ((240 - (ALPHA_BTN_SPACING * 6)) / 5) +// #define ALPHA_KEYPAD_TOP ((320 / 6) + (ALPHA_BTN_SPACING * 2)) +// #define ALPHA_BTN_HEIGHT (((320 - ALPHA_KEYPAD_TOP) - (ALPHA_BTN_SPACING * 7)) / 6) + +/* X/Y positions for buttons */ +#define ALPHA_ROW1_TOP (ALPHA_KEYPAD_TOP + ALPHA_BTN_SPACING) +#define ALPHA_ROW2_TOP (ALPHA_KEYPAD_TOP + ALPHA_BTN_HEIGHT + (ALPHA_BTN_SPACING * 2)) +#define ALPHA_ROW3_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 2) + ((ALPHA_BTN_SPACING) * 3))) +#define ALPHA_ROW4_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 3) + ((ALPHA_BTN_SPACING) * 4))) +#define ALPHA_ROW5_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 4) + ((ALPHA_BTN_SPACING) * 5))) +#define ALPHA_ROW6_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 5) + ((ALPHA_BTN_SPACING) * 6))) +#define ALPHA_COL1_LEFT (ALPHA_BTN_SPACING) +#define ALPHA_COL2_LEFT ((ALPHA_BTN_SPACING * 2) + ALPHA_BTN_WIDTH) +#define ALPHA_COL3_LEFT ((ALPHA_BTN_SPACING * 3) + (ALPHA_BTN_WIDTH * 2)) +#define ALPHA_COL4_LEFT ((ALPHA_BTN_SPACING * 4) + (ALPHA_BTN_WIDTH * 3)) +#define ALPHA_COL5_LEFT ((ALPHA_BTN_SPACING * 5) + (ALPHA_BTN_WIDTH * 4)) + +/* Control which 'page' is currently shown on the keypad */ +static uint8_t alphaPage = 0; + +/* Keeps track of the string contents */ +static uint8_t alphaString[80]; +static uint8_t *alphaString_ptr; + +/* For quick retrieval of button X/Y locqtions */ +uint32_t alphaBtnX[5], alphaBtnY[6]; + +/* Array showing which characters should be displayed on each alphaPage */ +/* You can rearrange the keypad by modifying the array contents below */ +/* -------------------- -------------------- -------------------- -------------------- + A B C D BACK a b c d BACK . , : ; BACK 7 8 9 BACK + E F G H I e f g h i ' " ( ) 4 5 6 + J K L M N j k l m n ? ! { } 7 8 9 + O P Q R S o p q r s # & @ ~ . 0 SPC + T U V W SHFT t u v w SHFT % = / \ SHFT SHFT + X Y Z SPC OK x y z SPC OK + - _ SPC OK OK + -------------------- -------------------- -------------------- -------------------- */ +char alphaKeys[4][6][5] = { { { 'A', 'B', 'C', 'D', '<' }, + { 'E', 'F', 'G', 'H', 'I' }, + { 'J', 'K', 'L', 'M', 'N' }, + { 'O', 'P', 'Q', 'R', 'S' }, + { 'T', 'U', 'V', 'W', '*' }, + { 'X', 'Y', 'Z', ' ', '>' } }, + + { { 'a', 'b', 'c', 'd', '<' }, + { 'e', 'f', 'g', 'h', 'i' }, + { 'j', 'k', 'l', 'm', 'n' }, + { 'o', 'p', 'q', 'r', 's' }, + { 't', 'u', 'v', 'w', '*' }, + { 'x', 'y', 'z', ' ', '>' } }, + + { { '.', ',', ':', ';', '<' }, + { '\'', '\"', '(', ')', ' ' }, + { '?', '!', '{', '}', ' ' }, + { '#', '&', '@', '~', ' ' }, + { '%', '=', '/', '\\', '*' }, + { '+', '-', '_', ' ', '>' } }, + + { { '7', '8', '9', ' ', '<' }, + { '4', '5', '6', ' ', ' ' }, + { '1', '2', '3', ' ', ' ' }, + { '.', '0', ' ', ' ', ' ' }, + { ' ', ' ', ' ', ' ', '*'}, + { ' ', ' ', ' ', ' ', '>' } } }; + +/**************************************************************************/ +/*! + @brief Renders the UI +*/ +/**************************************************************************/ +void alphaRenderButton(uint8_t alphaPage, uint8_t col, uint8_t row, bool selected) +{ + // Set colors depending on button state + uint16_t border, fill, font; + if (selected) + { + border = ALPHA_COLOR_BTNEN_BORDER; + fill = ALPHA_COLOR_BTNEN_FILL; + font = ALPHA_COLOR_BTNEN_FONT; + } + else + { + border = ALPHA_COLOR_BTN_BORDER; + fill = ALPHA_COLOR_BTN_FILL; + font = ALPHA_COLOR_BTN_FONT; + } + + char c = alphaKeys[alphaPage][row][col]; + char key[2] = { alphaKeys[alphaPage][row][col], '\0' }; + // Handle special characters + switch (c) + { + case '<': + // Backspace + drawButton (alphaBtnX[col], alphaBtnY[row], ALPHA_BTN_WIDTH, ALPHA_BTN_HEIGHT, &dejaVuSans9ptFontInfo, 7, border, fill, font, NULL); + drawArrow (alphaBtnX[col] + ALPHA_BTN_WIDTH / 2 - 3, alphaBtnY[row] + ALPHA_BTN_HEIGHT / 2, 7, DRAW_DIRECTION_LEFT, font); + break; + case '*': + // Page Shift + drawButton (alphaBtnX[col], alphaBtnY[row], ALPHA_BTN_WIDTH, ALPHA_BTN_HEIGHT, &dejaVuSans9ptFontInfo, 7, border, fill, font, NULL); + drawArrow (alphaBtnX[col] + ALPHA_BTN_WIDTH / 2, (alphaBtnY[row] + ALPHA_BTN_HEIGHT / 2) - 3, 7, DRAW_DIRECTION_UP, font); + break; + case '>': + // OK + drawButton (alphaBtnX[col], alphaBtnY[row], ALPHA_BTN_WIDTH, ALPHA_BTN_HEIGHT, &dejaVuSans9ptFontInfo, 7, border, fill, font, "OK"); + break; + default: + // Standard character + drawButton (alphaBtnX[col], alphaBtnY[row], ALPHA_BTN_WIDTH, ALPHA_BTN_HEIGHT, &dejaVuSans9ptFontInfo, 7, border, fill, font, key); + break; + } +} + +/**************************************************************************/ +/*! + @brief Renders the UI +*/ +/**************************************************************************/ +void alphaRefreshScreen(void) +{ + uint8_t x, y; + + /* Draw keypad */ + for (y = 0; y < 6; y++) + { + for (x = 0; x < 5; x++) + { + alphaRenderButton(alphaPage, x, y, false); + } + } + + /* Render Text */ + drawRectangleRounded(ALPHA_BTN_SPACING, ALPHA_BTN_SPACING, lcdGetWidth() - 1 - ALPHA_BTN_SPACING, ALPHA_KEYPAD_TOP - ALPHA_BTN_SPACING, ALPHA_COLOR_INPUTFILL, 10, DRAW_ROUNDEDCORNERS_ALL); + drawString(ALPHA_BTN_SPACING * 3, ALPHA_BTN_SPACING * 3, ALPHA_COLOR_INPUTTEXT, &dejaVuSans9ptFontInfo, (char *)&alphaString); +} + +/**************************************************************************/ +/*! + @brief Processes the supplied touch data +*/ +/**************************************************************************/ +char alphaHandleTouchEvent(void) +{ + tsTouchData_t data; + char result = '\0'; + uint8_t row, col; + int32_t tsError = -1; + + // Blocking delay until a valid touch event occurs + while (tsError) + { + tsError = tsWaitForEvent(&data, 0); + } + + // Attempt to convert touch data to char + if ((data.ylcd < ALPHA_ROW1_TOP) || (data.ylcd > ALPHA_ROW6_TOP + ALPHA_BTN_HEIGHT)) + { + return result; + } + + // Get column + if ((data.xlcd > alphaBtnX[0]) && (data.xlcd < alphaBtnX[0] + ALPHA_BTN_WIDTH)) + col = 0; + else if ((data.xlcd > alphaBtnX[1]) && (data.xlcd < alphaBtnX[1] + ALPHA_BTN_WIDTH)) + col = 1; + else if ((data.xlcd > alphaBtnX[2]) && (data.xlcd < alphaBtnX[2] + ALPHA_BTN_WIDTH)) + col = 2; + else if ((data.xlcd > alphaBtnX[3]) && (data.xlcd < alphaBtnX[3] + ALPHA_BTN_WIDTH)) + col = 3; + else if ((data.xlcd > ALPHA_COL5_LEFT) && (data.xlcd < ALPHA_COL5_LEFT + ALPHA_BTN_WIDTH)) + col = 4; + else + return result; + + // Get row + if ((data.ylcd > ALPHA_ROW1_TOP) && (data.ylcd < ALPHA_ROW1_TOP + ALPHA_BTN_HEIGHT)) + row = 0; + else if ((data.ylcd > ALPHA_ROW2_TOP) && (data.ylcd < ALPHA_ROW2_TOP + ALPHA_BTN_HEIGHT)) + row = 1; + else if ((data.ylcd > ALPHA_ROW3_TOP) && (data.ylcd < ALPHA_ROW3_TOP + ALPHA_BTN_HEIGHT)) + row = 2; + else if ((data.ylcd > ALPHA_ROW4_TOP) && (data.ylcd < ALPHA_ROW4_TOP + ALPHA_BTN_HEIGHT)) + row = 3; + else if ((data.ylcd > ALPHA_ROW5_TOP) && (data.ylcd < ALPHA_ROW5_TOP + ALPHA_BTN_HEIGHT)) + row = 4; + else if ((data.ylcd > ALPHA_ROW6_TOP) && (data.ylcd < ALPHA_ROW6_TOP + ALPHA_BTN_HEIGHT)) + row = 5; + else + return result; + + // Match found ... update button and process the results + alphaRenderButton(alphaPage, col, row, true); + result = alphaKeys[alphaPage][row][col]; + + if (result == '<') + { + // Trim character if backspace was pressed + if (alphaString_ptr > alphaString) + { + alphaString_ptr--; + *alphaString_ptr = '\0'; + } + } + else if (result == '*') + { + // Switch page if the shift button was pressed + alphaPage++; + if (alphaPage > 3) + { + alphaPage = 0; + } + // Update the UI + alphaRefreshScreen(); + } + else if (result == '>') + { + // OK button + systickDelay(CFG_TFTLCD_TS_KEYPADDELAY); + return '>'; + } + else + { + // Add text to string buffer + *alphaString_ptr++ = result; + } + + // Brief delay + systickDelay(CFG_TFTLCD_TS_KEYPADDELAY); + + // Return button to deselected state + alphaRefreshScreen(); + return result; +} + +/**************************************************************************/ +/*! + @brief Displays the dialogue box and waits for valid user input + + @section Example + + @code + #include "drivers/lcd/tft/dialogues/alphanumeric.h" + + // Print results from an alpha-numeric dialogue + char* results = alphaShowDialogue(); + printf("%s\r\n", results); + + @endcode +*/ +/**************************************************************************/ +char* alphaShowDialogue(void) +{ + char result; + + /* These need to be instantiated here since the width and height of + the lcd is retrieved dynamically depending on screen orientation */ + alphaBtnX[0] = ALPHA_COL1_LEFT; + alphaBtnX[1] = ALPHA_COL2_LEFT; + alphaBtnX[2] = ALPHA_COL3_LEFT; + alphaBtnX[3] = ALPHA_COL4_LEFT; + alphaBtnX[4] = ALPHA_COL5_LEFT; + alphaBtnY[0] = ALPHA_ROW1_TOP; + alphaBtnY[1] = ALPHA_ROW2_TOP; + alphaBtnY[2] = ALPHA_ROW3_TOP; + alphaBtnY[3] = ALPHA_ROW4_TOP; + alphaBtnY[4] = ALPHA_ROW5_TOP; + alphaBtnY[5] = ALPHA_ROW6_TOP; + + /* Initialise the string buffer */ + memset(&alphaString[0], 0, sizeof(alphaString)); + alphaString_ptr = alphaString; + alphaPage = 0; + + /* Draw the background and render the buttons */ + drawFill(ALPHA_COLOR_BACKGROUND); + alphaRefreshScreen(); + + /* Capture results until the 'OK' button is pressed */ + while(1) + { + result = alphaHandleTouchEvent(); + if (result == '>') return (char *)&alphaString; + } +} diff --git a/drivers/lcd/tft/dialogues/alphanumeric.h b/drivers/lcd/tft/dialogues/alphanumeric.h new file mode 100644 index 0000000..13353f8 --- /dev/null +++ b/drivers/lcd/tft/dialogues/alphanumeric.h @@ -0,0 +1,43 @@ +/**************************************************************************/ +/*! + @file alphanumeric.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __DIALOGUE_ALPHANUMERIC_H__ +#define __DIALOGUE_ALPHANUMERIC_H__ + +#include "projectconfig.h" + +char * alphaShowDialogue(void); + +#endif diff --git a/drivers/lcd/tft/drawing.c b/drivers/lcd/tft/drawing.c new file mode 100644 index 0000000..cd612e6 --- /dev/null +++ b/drivers/lcd/tft/drawing.c @@ -0,0 +1,1205 @@ +/**************************************************************************/ +/*! + @file drawing.c + @author K. Townsend (microBuilder.eu) + + drawLine and drawCircle adapted from a tutorial by Leonard McMillan: + http://www.cs.unc.edu/~mcmillan/ + + drawString based on an example from Eran Duchan: + http://www.pavius.net/downloads/tools/53-the-dot-factory + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "drawing.h" + +#ifdef CFG_SDCARD + #include "bmp.h" +#endif + +/**************************************************************************/ +/* */ +/* ----------------------- Private Methods ------------------------------ */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Draws a single bitmap character +*/ +/**************************************************************************/ +void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const uint8_t *glyph, uint8_t glyphHeightPages, uint8_t glyphWidthBits) +{ + uint16_t verticalPage, horizBit, currentY, currentX; + uint16_t indexIntoGlyph; + + // set initial current y + currentY = yPixel; + currentX = xPixel; + + // for each page of the glyph + for (verticalPage = glyphHeightPages; verticalPage > 0; --verticalPage) + { + // for each horizontol bit + for (horizBit = 0; horizBit < glyphWidthBits; ++horizBit) + { + // next byte + indexIntoGlyph = (glyphHeightPages * horizBit) + verticalPage - 1; + + currentX = xPixel + (horizBit); + // send the data byte + if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color); + if (glyph[indexIntoGlyph] & (0X40)) drawPixel(currentX, currentY - 1, color); + if (glyph[indexIntoGlyph] & (0X20)) drawPixel(currentX, currentY - 2, color); + if (glyph[indexIntoGlyph] & (0X10)) drawPixel(currentX, currentY - 3, color); + if (glyph[indexIntoGlyph] & (0X08)) drawPixel(currentX, currentY - 4, color); + if (glyph[indexIntoGlyph] & (0X04)) drawPixel(currentX, currentY - 5, color); + if (glyph[indexIntoGlyph] & (0X02)) drawPixel(currentX, currentY - 6, color); + if (glyph[indexIntoGlyph] & (0X01)) drawPixel(currentX, currentY - 7, color); + } + // next line of pages + currentY += 8; + } +} + +#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1 +/**************************************************************************/ +/*! + @brief Draws a single smallfont character +*/ +/**************************************************************************/ +void drawCharSmall(uint16_t x, uint16_t y, uint16_t color, uint8_t c, struct FONT_DEF font) +{ + uint8_t col, column[font.u8Width]; + + // Check if the requested character is available + if ((c >= font.u8FirstChar) && (c <= font.u8LastChar)) + { + // Retrieve appropriate columns from font data + for (col = 0; col < font.u8Width; col++) + { + column[col] = font.au8FontTable[((c - 32) * font.u8Width) + col]; // Get first column of appropriate character + } + } + else + { + // Requested character is not available in this font ... send a space instead + for (col = 0; col < font.u8Width; col++) + { + column[col] = 0xFF; // Send solid space + } + } + + // Render each column + uint16_t xoffset, yoffset; + for (xoffset = 0; xoffset < font.u8Width; xoffset++) + { + for (yoffset = 0; yoffset < (font.u8Height + 1); yoffset++) + { + uint8_t bit = 0x00; + bit = (column[xoffset] << (8 - (yoffset + 1))); // Shift current row bit left + bit = (bit >> 7); // Shift current row but right (results in 0x01 for black, and 0x00 for white) + if (bit) + { + drawPixel(x + xoffset, y + yoffset, color); + } + } + } +} +#endif + +/**************************************************************************/ +/*! + @brief Helper method to accurately draw individual circle points +*/ +/**************************************************************************/ +void drawCirclePoints(int cx, int cy, int x, int y, uint16_t color) +{ + if (x == 0) + { + drawPixel(cx, cy + y, color); + drawPixel(cx, cy - y, color); + drawPixel(cx + y, cy, color); + drawPixel(cx - y, cy, color); + } + else if (x == y) + { + drawPixel(cx + x, cy + y, color); + drawPixel(cx - x, cy + y, color); + drawPixel(cx + x, cy - y, color); + drawPixel(cx - x, cy - y, color); + } + else if (x < y) + { + drawPixel(cx + x, cy + y, color); + drawPixel(cx - x, cy + y, color); + drawPixel(cx + x, cy - y, color); + drawPixel(cx - x, cy - y, color); + drawPixel(cx + y, cy + x, color); + drawPixel(cx - y, cy + x, color); + drawPixel(cx + y, cy - x, color); + drawPixel(cx - y, cy - x, color); + } +} + +/**************************************************************************/ +/* */ +/* ----------------------- Public Methods ------------------------------- */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Draws a single pixel at the specified location + + @param[in] x + Horizontal position + @param[in] y + Vertical position + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + if ((x >= lcdGetWidth()) || (y >= lcdGetHeight())) + { + // Pixel out of range + return; + } + + // Redirect to LCD + lcdDrawPixel(x, y, color); +} + +/**************************************************************************/ +/*! + @brief Fills the screen with the specified color + + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawFill(uint16_t color) +{ + lcdFillRGB(color); +} + +/**************************************************************************/ +/*! + @brief Draws a simple color test pattern +*/ +/**************************************************************************/ +void drawTestPattern(void) +{ + lcdTest(); +} + +#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1 +/**************************************************************************/ +/*! + @brief Draws a string using a small font (6 of 8 pixels high). + + @param[in] x + Starting x co-ordinate + @param[in] y + Starting y co-ordinate + @param[in] color + Color to use when rendering the font + @param[in] text + The string to render + @param[in] font + Pointer to the FONT_DEF to use when drawing the string + + @section Example + + @code + + #include "drivers/lcd/fonts/smallfonts.h" + + drawStringSmall(1, 210, COLOR_WHITE, "5x8 System (Max 40 Characters)", Font_System5x8); + drawStringSmall(1, 220, COLOR_WHITE, "7x8 System (Max 30 Characters)", Font_System7x8); + + @endcode +*/ +/**************************************************************************/ +void drawStringSmall(uint16_t x, uint16_t y, uint16_t color, char* text, struct FONT_DEF font) +{ + uint8_t l; + for (l = 0; l < strlen(text); l++) + { + drawCharSmall(x + (l * (font.u8Width + 1)), y, color, text[l], font); + } +} +#endif + +/**************************************************************************/ +/*! + @brief Draws a string using the supplied font + + @param[in] x + Starting x co-ordinate + @param[in] y + Starting y co-ordinate + @param[in] color + Color to use when rendering the font + @param[in] fontInfo + Pointer to the FONT_INFO to use when drawing the string + @param[in] str + The string to render + + @section Example + + @code + + #include "drivers/lcd/tft/fonts/veramono9.h" + + drawString(0, 90, COLOR_BLACK, &bitstreamVeraSansMono9ptFontInfo, "Vera Mono 9 (30 chars wide)"); + drawString(0, 105, COLOR_BLACK, &bitstreamVeraSansMono9ptFontInfo, "123456789012345678901234567890"); + + @endcode +*/ +/**************************************************************************/ +void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str) +{ + uint16_t currentX, charWidth, characterToOutput; + const FONT_CHAR_INFO *charInfo; + uint16_t charOffset; + + // set current x, y to that of requested + currentX = x; + + // while not NULL + while (*str != '\0') + { + // get character to output + characterToOutput = *str; + + // get char info + charInfo = fontInfo->charInfo; + + // some fonts have character descriptors, some don't + if (charInfo != NULL) + { + // get correct char offset + charInfo += (characterToOutput - fontInfo->startChar); + + // get width from char info + charWidth = charInfo->widthBits; + + // get offset from char info + charOffset = charInfo->offset; + } + else + { + // if no char info, char width is always 5 + charWidth = 5; + + // char offset - assume 5 * letter offset + charOffset = (characterToOutput - fontInfo->startChar) * 5; + } + + // Send individual characters + drawCharBitmap(currentX, y, color, &fontInfo->data[charOffset], fontInfo->heightPages, charWidth); + + // next char X + currentX += charWidth + 1; + + // next char + str++; + } +} + +/**************************************************************************/ +/*! + @brief Returns the width in pixels of a string when it is rendered + + This method can be used to determine whether a string will fit + inside a specific area, or if it needs to be broken up into multiple + lines to be properly rendered on the screen. + + This function only applied to bitmap fonts (which can have variable + widths). All smallfonts (if available) are fixed width and can + easily have their width calculated without costly functions like + this one. + + @param[in] fontInfo + Pointer to the FONT_INFO for the font that will be used + @param[in] str + The string that will be rendered +*/ +/**************************************************************************/ +uint16_t drawGetStringWidth(const FONT_INFO *fontInfo, char *str) +{ + uint16_t width = 0; + uint32_t currChar; + uint32_t startChar = fontInfo->startChar; + + // until termination + for (currChar = *str; currChar; currChar = *(++str)) + { + // if char info exists for the font, use width from there + if (fontInfo->charInfo != NULL) + { + width += fontInfo->charInfo[currChar - startChar].widthBits + 1; + } + else + { + width += 5 + 1; + } + } + + /* return the wdith */ + return width; +} + +/**************************************************************************/ +/*! + @brief Draws a bresenham line + + @param[in] x0 + Starting x co-ordinate + @param[in] y0 + Starting y co-ordinate + @param[in] x1 + Ending x co-ordinate + @param[in] y1 + Ending y co-ordinate + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawLine ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color ) +{ + drawLineDotted(x0, y0, x1, y1, 0, 1, color); +} + +/**************************************************************************/ +/*! + @brief Draws a bresenham line with a fixed pattern of empty + and solid pixels + + Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html + + @param[in] x0 + Starting x co-ordinate + @param[in] y0 + Starting y co-ordinate + @param[in] x1 + Ending x co-ordinate + @param[in] y1 + Ending y co-ordinate + @param[in] empty + The number of 'empty' pixels to render + @param[in] solid + The number of 'solid' pixels to render + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawLineDotted ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t empty, uint16_t solid, uint16_t color ) +{ + if (solid == 0) + { + return; + } + + // If a negative y int was passed in it will overflow to 65K something + // Ugly, but drawCircleFilled() can pass in negative values so we need + // to check the values here + y0 = y0 > 65000 ? 0 : y0; + y1 = y1 > 65000 ? 0 : y1; + + // Check if we can use the optimised horizontal line method + if ((y0 == y1) && (empty == 0)) + { + lcdDrawHLine(x0, x1, y0, color); + return; + } + + // Check if we can use the optimised vertical line method. + // This can make a huge difference in performance, but may + // not work properly on every LCD controller: + // ex.: drawCircleFilled(120, 160, 50, COLOR_RED); + // = 678834 cycles using lcdDrawVLine w/ILI9328 = 9.43mS @ 72MHz + // = 7546261 w/o lcdDrawVLine, setting each pixel = 104.8mS @ 72MHz + if ((x0 == x1) && (empty == 0)) + { + // Warning: This may actually be slower than drawing individual pixels on + // short lines ... Set a minimum line size to use the 'optimised' method + // (which changes the screen orientation) ? + lcdDrawVLine(x0, y0, y1, color); + return; + } + + // Draw non-horizontal or dotted line + int dy = y1 - y0; + int dx = x1 - x0; + int stepx, stepy; + int emptycount, solidcount; + + if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } + if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } + dy <<= 1; // dy is now 2*dy + dx <<= 1; // dx is now 2*dx + + emptycount = empty; + solidcount = solid; + + drawPixel(x0, y0, color); // always start with solid pixels + solidcount--; + if (dx > dy) + { + int fraction = dy - (dx >> 1); // same as 2*dy - dx + while (x0 != x1) + { + if (fraction >= 0) + { + y0 += stepy; + fraction -= dx; // same as fraction -= 2*dx + } + x0 += stepx; + fraction += dy; // same as fraction -= 2*dy + if (empty == 0) + { + // always draw a pixel ... no dotted line requested + drawPixel(x0, y0, color); + } + else if (solidcount) + { + // Draw solid pxiel and decrement counter + drawPixel(x0, y0, color); + solidcount--; + } + else if(emptycount) + { + // Empty pixel ... don't draw anything an decrement counter + emptycount--; + } + else + { + // Reset counters and draw solid pixel + emptycount = empty; + solidcount = solid; + drawPixel(x0, y0, color); + solidcount--; + } + } + } + else + { + int fraction = dx - (dy >> 1); + while (y0 != y1) + { + if (fraction >= 0) + { + x0 += stepx; + fraction -= dy; + } + y0 += stepy; + fraction += dx; + if (empty == 0) + { + // always draw a pixel ... no dotted line requested + drawPixel(x0, y0, color); + } + if (solidcount) + { + // Draw solid pxiel and decrement counter + drawPixel(x0, y0, color); + solidcount--; + } + else if(emptycount) + { + // Empty pixel ... don't draw anything an decrement counter + emptycount--; + } + else + { + // Reset counters and draw solid pixel + emptycount = empty; + solidcount = solid; + drawPixel(x0, y0, color); + solidcount--; + } + } + } +} + +/**************************************************************************/ +/*! + @brief Draws a circle + + Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html + + @param[in] xCenter + The horizontal center of the circle + @param[in] yCenter + The vertical center of the circle + @param[in] radius + The circle's radius in pixels + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawCircle (uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color) +{ + int x = 0; + int y = radius; + int p = (5 - radius*4)/4; + + drawCirclePoints(xCenter, yCenter, x, y, color); + while (x < y) + { + x++; + if (p < 0) + { + p += 2*x+1; + } + else + { + y--; + p += 2*(x-y)+1; + } + drawCirclePoints(xCenter, yCenter, x, y, color); + } +} + +/**************************************************************************/ +/*! + @brief Draws a filled circle + + @param[in] xCenter + The horizontal center of the circle + @param[in] yCenter + The vertical center of the circle + @param[in] radius + The circle's radius in pixels + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawCircleFilled (uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color) +{ + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; + int16_t xc_px, yc_my, xc_mx, xc_py, yc_mx, xc_my; + int16_t lcdWidth = lcdGetWidth(); + + if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter-radius, xCenter, (yCenter-radius) + (2*radius), color); + + while (x= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + xc_px = xCenter+x; + xc_mx = xCenter-x; + xc_py = xCenter+y; + xc_my = xCenter-y; + yc_mx = yCenter-x; + yc_my = yCenter-y; + + // Make sure X positions are not negative or too large or the pixels will + // overflow. Y overflow is handled in drawLine(). + if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yc_my, xc_px, yc_my + 2*y, color); + if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yc_my, xc_mx, yc_my + 2*y, color); + if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yc_mx, xc_py, yc_mx + 2*x, color); + if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yc_mx, xc_my, yc_mx + 2*x, color); + } +} + +/**************************************************************************/ +/*! + @brief Draws a simple arrow of the specified width + + @param[in] x + X co-ordinate of the smallest point of the arrow + @param[in] y + Y co-ordinate of the smallest point of the arrow + @param[in] size + Total width/height of the arrow in pixels + @param[in] direction + The direction that the arrow is pointing + @param[in] color + Color used when drawing +*/ +/**************************************************************************/ +void drawArrow(uint16_t x, uint16_t y, uint16_t size, drawDirection_t direction, uint16_t color) +{ + drawPixel(x, y, color); + + if (size == 1) + { + return; + } + + uint32_t i; + switch (direction) + { + case DRAW_DIRECTION_LEFT: + for (i = 1; i height - 1; ++height) + { + drawLine(x0, height, x1, height, color); + } +} + +/**************************************************************************/ +/*! + @brief Draws a filled rectangle with rounded corners + + @param[in] x0 + Starting x co-ordinate + @param[in] y0 + Starting y co-ordinate + @param[in] x1 + Ending x co-ordinate + @param[in] y1 + Ending y co-ordinate + @param[in] color + Color used when drawing + @param[in] radius + Corner radius in pixels + @param[in] corners + Which corners to round +*/ +/**************************************************************************/ +void drawRectangleRounded ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawRoundedCorners_t corners ) +{ + int height; + uint16_t y; + + if (corners == DRAW_ROUNDEDCORNERS_NONE) + { + drawRectangleFilled(x0, y0, x1, y1, color); + return; + } + + // Calculate height + if (y1 < y0) + { + y = y1; + y1 = y0; + y0 = y; + } + height = y1 - y0; + + // Check radius + if (radius > height / 2) + { + radius = height / 2; + } + radius -= 1; + + // Draw body + drawRectangleFilled(x0 + radius, y0, x1 - radius, y1, color); + + switch (corners) + { + case DRAW_ROUNDEDCORNERS_ALL: + drawCircleFilled(x0 + radius, y0 + radius, radius, color); + drawCircleFilled(x1 - radius, y0 + radius, radius, color); + drawCircleFilled(x0 + radius, y1 - radius, radius, color); + drawCircleFilled(x1 - radius, y1 - radius, radius, color); + if (radius*2+1 < height) + { + drawRectangleFilled(x0, y0 + radius, x0 + radius, y1 - radius, color); + drawRectangleFilled(x1 - radius, y0 + radius, x1, y1 - radius, color); + } + break; + case DRAW_ROUNDEDCORNERS_TOP: + drawCircleFilled(x0 + radius, y0 + radius, radius, color); + drawCircleFilled(x1 - radius, y0 + radius, radius, color); + drawRectangleFilled(x0, y0 + radius, x0 + radius, y1, color); + drawRectangleFilled(x1 - radius, y0 + radius, x1, y1, color); + break; + case DRAW_ROUNDEDCORNERS_BOTTOM: + drawCircleFilled(x0 + radius, y1 - radius, radius, color); + drawCircleFilled(x1 - radius, y1 - radius, radius, color); + drawRectangleFilled(x0, y0, x0 + radius, y1 - radius, color); + drawRectangleFilled(x1 - radius, y0, x1, y1 - radius, color); + break; + case DRAW_ROUNDEDCORNERS_LEFT: + drawCircleFilled(x0 + radius, y0 + radius, radius, color); + drawCircleFilled(x0 + radius, y1 - radius, radius, color); + if (radius*2+1 < height) + { + drawRectangleFilled(x0, y0 + radius, x0 + radius, y1 - radius, color); + } + drawRectangleFilled(x1 - radius, y0, x1, y1, color); + break; + case DRAW_ROUNDEDCORNERS_RIGHT: + drawCircleFilled(x1 - radius, y0 + radius, radius, color); + drawCircleFilled(x1 - radius, y1 - radius, radius, color); + if (radius*2+1 < height) + { + drawRectangleFilled(x1 - radius, y0 + radius, x1, y1 - radius, color); + } + drawRectangleFilled(x0, y0, x0 + radius, y1, color); + break; + default: + break; + } +} + +/**************************************************************************/ +/*! + @brief Converts a 24-bit RGB color to an equivalent 16-bit RGB565 value + + @param[in] r + 8-bit red + @param[in] g + 8-bit green + @param[in] b + 8-bit blue + + @section Example + + @code + + // Get 16-bit equivalent of 24-bit color + uint16_t gray = drawRGB24toRGB565(0x33, 0x33, 0x33); + + @endcode +*/ +/**************************************************************************/ +uint16_t drawRGB24toRGB565(uint8_t r, uint8_t g, uint8_t b) +{ + return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8); +} + +/**************************************************************************/ +/*! + @brief Converts a 16-bit RGB565 color to a standard 32-bit BGRA32 + color (with alpha set to 0xFF) + + @param[in] color + 16-bit rgb565 color + + @section Example + + @code + + // First convert 24-bit color to RGB565 + uint16_t rgb565 = drawRGB24toRGB565(0xFF, 0x00, 0x00); + + // Convert RGB565 color back to BGRA32 + uint32_t bgra32 = drawRGB565toBGRA32(rgb565); + + // Display results + printf("BGRA32: 0x%08X R: %u G: %u B: %u A: %u \r\n", + bgra32, + (bgra32 & 0x000000FF), // Blue + (bgra32 & 0x0000FF00) >> 8, // Green + (bgra32 & 0x00FF0000) >> 16, // Red + (bgra32 & 0xFF000000) >> 24); // Alpha + + @endcode +*/ +/**************************************************************************/ +uint32_t drawRGB565toBGRA32(uint16_t color) +{ + uint32_t bits = (uint32_t)color; + uint32_t blue = bits & 0x001F; // 5 bits blue + uint32_t green = bits & 0x07E0; // 6 bits green + uint32_t red = bits & 0xF800; // 5 bits red + + // Return shifted bits with alpha set to 0xFF + return (red << 8) | (green << 5) | (blue << 3) | 0xFF000000; +} + +/**************************************************************************/ +/*! + @brief Reverses a 16-bit color from BGR to RGB +*/ +/**************************************************************************/ +uint16_t drawBGR2RGB(uint16_t color) +{ + uint16_t r, g, b; + + b = (color>>0) & 0x1f; + g = (color>>5) & 0x3f; + r = (color>>11) & 0x1f; + + return( (b<<11) + (g<<5) + (r<<0) ); +} + +/**************************************************************************/ +/*! + @brief Draws a progress bar with rounded corners + + @param[in] x + Starting x location + @param[in] y + Starting y location + @param[in] width + Total width of the progress bar in pixels + @param[in] height + Total height of the progress bar in pixels + @param[in] borderCorners + The type of rounded corners to render with the progress bar border + @param[in] progressCorners + The type of rounded corners to render with the inner progress bar + @param[in] borderColor + 16-bit color for the outer border + @param[in] borderFillColor + 16-bit color for the interior of the outer border + @param[in] progressBorderColor + 16-bit color for the progress bar's border + @param[in] progressFillColor + 16-bit color for the inner bar's fill + @param[in] progress + Progress percentage (between 0 and 100) + + @section Example + + @code + #include "drivers/lcd/tft/drawing.h" + + // Draw a the progress bar (150x15 pixels large, starting at X:10, Y:195 + // with rounded corners on the top and showing 72% progress) + drawProgressBar(10, 195, 150, 15, DRAW_ROUNDEDCORNERS_TOP, DRAW_ROUNDEDCORNERS_TOP, COLOR_DARKERGRAY, COLOR_DARKGRAY, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, 72 ); + + @endcode +*/ +/**************************************************************************/ +void drawProgressBar ( uint16_t x, uint16_t y, uint16_t width, uint16_t height, drawRoundedCorners_t borderCorners, drawRoundedCorners_t progressCorners, uint16_t borderColor, uint16_t borderFillColor, uint16_t progressBorderColor, uint16_t progressFillColor, uint8_t progress ) +{ + // Draw border with rounded corners + drawRectangleRounded(x, y, x + width, y + height, borderColor, 5, borderCorners); + drawRectangleRounded(x+1, y+1, x + width - 1, y + height - 1, borderFillColor, 5, borderCorners); + + // Progress bar + if (progress > 0 && progress <= 100) + { + // Calculate bar size + uint16_t bw; + bw = (width - 6); // bar at 100% + if (progress != 100) + { + bw = (bw * progress) / 100; + } + drawRectangleRounded(x + 3, y + 3, bw + x + 3, y + height - 3, progressBorderColor, 5, progressCorners); + drawRectangleRounded(x + 4, y + 4, bw + x + 3 - 1, y + height - 4, progressFillColor, 5, progressCorners); + } +} + +/**************************************************************************/ +/*! + @brief Draws a simple button + + @param[in] x + Starting x location + @param[in] y + Starting y location + @param[in] width + Total width of the button in pixels + @param[in] height + Total height of the button in pixels + @param[in] fontInfo + Pointer to the FONT_INFO used to render the button text + @param[in] fontHeight + The height in pixels of the font (used for centering) + @param[in] borderclr + The rgb565 border color + @param[in] fillclr + The rgb565 background color + @param[in] fontclr + The rgb565 font color + @param[in] text + The text to render on the button + + @section Example + + @code + + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/tft/fonts/dejavusansbold9.h" + + // Draw two buttons using Vera Sans Bold 9 + drawButton(20, 195, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_DARKERGRAY, COLOR_DARKERGRAY, COLOR_WHITE, "System Settings"); + drawButton(20, 235, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, COLOR_BLACK, "System Settings"); + + @endcode +*/ +/**************************************************************************/ +void drawButton(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const FONT_INFO *fontInfo, uint16_t fontHeight, uint16_t borderclr, uint16_t fillclr, uint16_t fontclr, char* text) +{ + uint16_t border, fill, font, activeborder, activefill, activefont; + + // Set colors + border = COLOR_GRAY_30; + fill = COLOR_GRAY_30; + font = COLOR_WHITE; + activeborder = COLOR_THEME_DEFAULT_DARKER; + activefill = COLOR_THEME_DEFAULT_BASE; + activefont = COLOR_BLACK; + + // Border + drawRectangleRounded(x, y, x + width, y + height, borderclr, 5, DRAW_ROUNDEDCORNERS_ALL); + // Fill + drawRectangleRounded(x+2, y+2, x+width-2, y+height-2, fillclr, 5, DRAW_ROUNDEDCORNERS_ALL); + + // Render text + if (text != NULL) + { + uint16_t textWidth = drawGetStringWidth(&*fontInfo, text); + uint16_t xStart = x + (width / 2) - (textWidth / 2); + uint16_t yStart = y + (height / 2) - (fontHeight / 2) + 1; + drawString(xStart, yStart, fontclr, &*fontInfo, text); + } +} + +/**************************************************************************/ +/*! + @brief Renders a 16x16 monochrome icon using the supplied uint16_t + array. + + @param[in] x + The horizontal location to start rendering from + @param[in] x + The vertical location to start rendering from + @param[in] color + The RGB565 color to use when rendering the icon + @param[in] icon + The uint16_t array containing the 16x16 image data + + @section Example + + @code + + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/icons16.h" + + // Renders the info icon, which has two seperate parts ... the exterior + // and a seperate interior mask if you want to fill the contents with a + // different color + drawIcon16(132, 202, COLOR_BLUE, icons16_info); + drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior); + + @endcode +*/ +/**************************************************************************/ +void drawIcon16(uint16_t x, uint16_t y, uint16_t color, uint16_t icon[]) +{ + int i; + uint16_t row; + for (i = 0; i<16; i++) + { + if (icon[i] & (0X8000)) drawPixel(x, y+i, color); + if (icon[i] & (0X4000)) drawPixel(x+1, y+i, color); + if (icon[i] & (0X2000)) drawPixel(x+2, y+i, color); + if (icon[i] & (0X1000)) drawPixel(x+3, y+i, color); + if (icon[i] & (0X0800)) drawPixel(x+4, y+i, color); + if (icon[i] & (0X0400)) drawPixel(x+5, y+i, color); + if (icon[i] & (0X0200)) drawPixel(x+6, y+i, color); + if (icon[i] & (0X0100)) drawPixel(x+7, y+i, color); + if (icon[i] & (0X0080)) drawPixel(x+8, y+i, color); + if (icon[i] & (0x0040)) drawPixel(x+9, y+i, color); + if (icon[i] & (0X0020)) drawPixel(x+10, y+i, color); + if (icon[i] & (0X0010)) drawPixel(x+11, y+i, color); + if (icon[i] & (0X0008)) drawPixel(x+12, y+i, color); + if (icon[i] & (0X0004)) drawPixel(x+13, y+i, color); + if (icon[i] & (0X0002)) drawPixel(x+14, y+i, color); + if (icon[i] & (0X0001)) drawPixel(x+15, y+i, color); + } +} + +#ifdef CFG_SDCARD +/**************************************************************************/ +/*! + @brief Loads a 24-bit Windows bitmap image from an SD card and + renders it + + @section Example + + @code + + #include "drivers/lcd/tft/drawing.h" + + // Draw image.bmp (from the root folder) starting at pixel 0,0 + bmp_error_t error = drawBitmapImage(0, 0, "/image.bmp"); + + if (error) + { + switch (error) + { + case BMP_ERROR_SDINITFAIL: + break; + case BMP_ERROR_FILENOTFOUND: + break; + case BMP_ERROR_NOTABITMAP: + // First two bytes of image not 'BM' + break; + case BMP_ERROR_INVALIDBITDEPTH: + // Image is not 24-bits + break; + case BMP_ERROR_COMPRESSEDDATA: + // Image contains compressed data + break; + case BMP_ERROR_INVALIDDIMENSIONS: + // Width or Height is > LCD size + break; + case BMP_ERROR_PREMATUREEOF: + // EOF unexpectedly reached in pixel data + break; + } + } + + @endcode +*/ +/**************************************************************************/ +bmp_error_t drawBitmapImage(uint16_t x, uint16_t y, char *filename) +{ + return bmpDrawBitmap(x, y, filename); +} + +#endif diff --git a/drivers/lcd/tft/drawing.h b/drivers/lcd/tft/drawing.h new file mode 100644 index 0000000..d9d1b1d --- /dev/null +++ b/drivers/lcd/tft/drawing.h @@ -0,0 +1,107 @@ +/**************************************************************************/ +/*! + @file drawing.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __DRAWING_H__ +#define __DRAWING_H__ + +#include "projectconfig.h" +#include "lcd.h" +#include "colors.h" +#include "drivers/lcd/tft/fonts/bitmapfonts.h" + +#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1 + #include "drivers/lcd/smallfonts.h" +#endif + +#ifdef CFG_SDCARD + #include "bmp.h" +#endif + +typedef struct +{ + uint8_t red; + uint8_t green; + uint8_t blue; +} drawColorRGB24_t; + +typedef enum +{ + DRAW_ROUNDEDCORNERS_NONE, + DRAW_ROUNDEDCORNERS_ALL, + DRAW_ROUNDEDCORNERS_TOP, + DRAW_ROUNDEDCORNERS_BOTTOM, + DRAW_ROUNDEDCORNERS_LEFT, + DRAW_ROUNDEDCORNERS_RIGHT +} drawRoundedCorners_t; + +typedef enum +{ + DRAW_DIRECTION_LEFT, + DRAW_DIRECTION_RIGHT, + DRAW_DIRECTION_UP, + DRAW_DIRECTION_DOWN +} drawDirection_t; + +void drawTestPattern ( void ); +void drawPixel ( uint16_t x, uint16_t y, uint16_t color ); +void drawFill ( uint16_t color ); +void drawLine ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color ); +void drawLineDotted ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t space, uint16_t solid, uint16_t color ); +void drawCircle ( uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color ); +void drawCircleFilled ( uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color ); +void drawArrow ( uint16_t x, uint16_t y, uint16_t size, drawDirection_t, uint16_t color ); +void drawRectangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color ); +void drawRectangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color ); +void drawRectangleRounded ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawRoundedCorners_t corners ); +void drawString ( uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str ); +uint16_t drawGetStringWidth ( const FONT_INFO *fontInfo, char *str ); +void drawProgressBar ( uint16_t x, uint16_t y, uint16_t width, uint16_t height, drawRoundedCorners_t borderCorners, drawRoundedCorners_t progressCorners, uint16_t borderColor, uint16_t borderFillColor, uint16_t progressBorderColor, uint16_t progressFillColor, uint8_t progress ); +void drawButton ( uint16_t x, uint16_t y, uint16_t width, uint16_t height, const FONT_INFO *fontInfo, uint16_t fontHeight, uint16_t borderclr, uint16_t fillclr, uint16_t fontclr, char* text ); +void drawIcon16 ( uint16_t x, uint16_t y, uint16_t color, uint16_t icon[] ); +uint16_t drawRGB24toRGB565 ( uint8_t r, uint8_t g, uint8_t b ); +uint32_t drawRGB565toBGRA32 ( uint16_t color ); +uint16_t drawBGR2RGB ( uint16_t color ); + +#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1 +void drawStringSmall ( uint16_t x, uint16_t y, uint16_t color, char* text, struct FONT_DEF font ); +#endif + +#if defined CFG_SDCARD +bmp_error_t drawBitmapImage ( uint16_t x, uint16_t y, char *filename ); +#endif + +#endif diff --git a/drivers/lcd/tft/fonts/bitmapfonts.h b/drivers/lcd/tft/fonts/bitmapfonts.h new file mode 100644 index 0000000..23fac6d --- /dev/null +++ b/drivers/lcd/tft/fonts/bitmapfonts.h @@ -0,0 +1,67 @@ +/**************************************************************************/ +/*! + @file bitmapfonts.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __BITMAPFONTS_H__ +#define __BITMAPFONTS_H__ + +#include "projectconfig.h" + +/**************************************************************************/ +/*! + @brief Describes a single character's display information +*/ +/**************************************************************************/ +typedef struct +{ + const uint8_t widthBits; // width, in bits (or pixels), of the character + const uint16_t offset; // offset of the character's bitmap, in bytes, into the the FONT_INFO's data array +} FONT_CHAR_INFO; + +/**************************************************************************/ +/*! + @brief Describes a single font +*/ +/**************************************************************************/ +typedef struct +{ + const uint8_t heightPages; // height, in pages (8 pixels), of the font's characters + const uint8_t startChar; // the first character in the font (e.g. in charInfo and data) + const FONT_CHAR_INFO* charInfo; // pointer to array of char information + const uint8_t* data; // pointer to generated array of character visual representation +} FONT_INFO; + +#endif diff --git a/drivers/lcd/tft/fonts/dejavusans9.c b/drivers/lcd/tft/fonts/dejavusans9.c new file mode 100644 index 0000000..1b4da96 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusans9.c @@ -0,0 +1,826 @@ +#include "dejavusans9.h" + +/* +** Font data for DejaVu Sans 9pt +*/ + +/* Character bitmaps for DejaVu Sans 9pt */ +const uint8_t dejaVuSans9ptCharBitmaps[] = +{ + /* @0 ' ' (5 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @10 '!' (1 pixels wide) */ + 0x1B, 0xF0, /* ## ###### */ + + /* @12 '"' (3 pixels wide) */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + + /* @18 '#' (8 pixels wide) */ + 0x04, 0x00, /* # */ + 0x14, 0x80, /* # # # */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xE0, /* # ### */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xC0, /* ##### */ + 0x04, 0xA0, /* # # # */ + 0x00, 0x80, /* # */ + + /* @34 '$' (5 pixels wide) */ + 0x09, 0xC0, /* # ### */ + 0x11, 0x20, /* # # # */ + 0x7F, 0xF0, /* ########### */ + 0x12, 0x20, /* # # # */ + 0x0E, 0x40, /* ### # */ + + /* @44 '%' (10 pixels wide) */ + 0x00, 0xE0, /* ### */ + 0x01, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x0C, 0xE0, /* ## ### */ + 0x03, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x0E, 0x60, /* ### ## */ + 0x11, 0x10, /* # # # */ + 0x11, 0x00, /* # # */ + 0x0E, 0x00, /* ### */ + + /* @64 '&' (8 pixels wide) */ + 0x0E, 0x00, /* ### */ + 0x19, 0xE0, /* ## #### */ + 0x10, 0x90, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x12, 0x20, /* # # # */ + 0x0C, 0x00, /* ## */ + 0x14, 0x00, /* # # */ + 0x13, 0x00, /* # ## */ + + /* @80 ''' (1 pixels wide) */ + 0x00, 0x70, /* ### */ + + /* @82 '(' (3 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x38, 0x38, /* ### ### */ + 0x20, 0x08, /* # # */ + + /* @88 ')' (3 pixels wide) */ + 0x20, 0x08, /* # # */ + 0x38, 0x38, /* ### ### */ + 0x07, 0xC0, /* ##### */ + + /* @94 '*' (5 pixels wide) */ + 0x01, 0x20, /* # # */ + 0x00, 0xC0, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + + /* @104 '+' (7 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @118 ',' (1 pixels wide) */ + 0x38, 0x00, /* ### */ + + /* @120 '-' (3 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @126 '.' (1 pixels wide) */ + 0x18, 0x00, /* ## */ + + /* @128 '/' (4 pixels wide) */ + 0x30, 0x00, /* ## */ + 0x0E, 0x00, /* ### */ + 0x01, 0xC0, /* ### */ + 0x00, 0x30, /* ## */ + + /* @136 '0' (6 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x07, 0xC0, /* ##### */ + + /* @148 '1' (5 pixels wide) */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @158 '2' (6 pixels wide) */ + 0x10, 0x20, /* # # */ + 0x18, 0x10, /* ## # */ + 0x14, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x11, 0x30, /* # # ## */ + 0x10, 0xE0, /* # ### */ + + /* @170 '3' (6 pixels wide) */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + + /* @182 '4' (6 pixels wide) */ + 0x06, 0x00, /* ## */ + 0x05, 0x80, /* # ## */ + 0x04, 0x40, /* # # */ + 0x04, 0x30, /* # ## */ + 0x1F, 0xF0, /* ######### */ + 0x04, 0x00, /* # */ + + /* @194 '5' (6 pixels wide) */ + 0x08, 0xF0, /* # #### */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x90, /* ## ## # */ + 0x0F, 0x00, /* #### */ + + /* @206 '6' (6 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x19, 0x20, /* ## # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x90, /* ## ## # */ + 0x0F, 0x20, /* #### # */ + + /* @218 '7' (6 pixels wide) */ + 0x00, 0x10, /* # */ + 0x10, 0x10, /* # # */ + 0x0C, 0x10, /* ## # */ + 0x03, 0x10, /* ## # */ + 0x00, 0xD0, /* ## # */ + 0x00, 0x30, /* ## */ + + /* @230 '8' (6 pixels wide) */ + 0x0E, 0xE0, /* ### ### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + + /* @242 '9' (6 pixels wide) */ + 0x09, 0xE0, /* # #### */ + 0x13, 0x30, /* # ## ## */ + 0x12, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x09, 0x30, /* # # ## */ + 0x07, 0xC0, /* ##### */ + + /* @254 ':' (1 pixels wide) */ + 0x19, 0x80, /* ## ## */ + + /* @256 ';' (1 pixels wide) */ + 0x39, 0x80, /* ### ## */ + + /* @258 '<' (8 pixels wide) */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x0C, 0xC0, /* ## ## */ + 0x08, 0x40, /* # # */ + + /* @274 '=' (8 pixels wide) */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + + /* @290 '>' (8 pixels wide) */ + 0x08, 0x40, /* # # */ + 0x0C, 0xC0, /* ## ## */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + + /* @306 '?' (5 pixels wide) */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x1B, 0x10, /* ## ## # */ + 0x00, 0x90, /* # # */ + 0x00, 0x60, /* ## */ + + /* @316 '@' (11 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x20, 0x20, /* # # */ + 0x47, 0x10, /* # ### # */ + 0x48, 0x90, /* # # # # */ + 0x48, 0x90, /* # # # # */ + 0x48, 0x90, /* # # # # */ + 0x4F, 0x90, /* # ##### # */ + 0x28, 0x20, /* # # # */ + 0x04, 0x60, /* # ## */ + 0x03, 0x80, /* ### */ + + /* @338 'A' (8 pixels wide) */ + 0x10, 0x00, /* # */ + 0x0E, 0x00, /* ### */ + 0x05, 0xC0, /* # ### */ + 0x04, 0x30, /* # ## */ + 0x04, 0x30, /* # ## */ + 0x05, 0xC0, /* # ### */ + 0x0E, 0x00, /* ### */ + 0x10, 0x00, /* # */ + + /* @354 'B' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + + /* @366 'C' (6 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + + /* @378 'D' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + 0x07, 0xC0, /* ##### */ + + /* @392 'E' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + + /* @404 'F' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + + /* @414 'G' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0F, 0x20, /* #### # */ + + /* @428 'H' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + + /* @442 'I' (1 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + + /* @444 'J' (3 pixels wide) */ + 0x40, 0x00, /* # */ + 0x40, 0x00, /* # */ + 0x3F, 0xF0, /* ########## */ + + /* @450 'K' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x02, 0x80, /* # # */ + 0x04, 0x40, /* # # */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + + /* @462 'L' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @472 'M' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x60, /* ## */ + 0x01, 0x80, /* ## */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0x60, /* ## */ + 0x1F, 0xF0, /* ######### */ + + /* @488 'N' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x30, /* ## */ + 0x00, 0xC0, /* ## */ + 0x01, 0x00, /* # */ + 0x06, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x1F, 0xF0, /* ######### */ + + /* @502 'O' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + 0x07, 0xC0, /* ##### */ + + /* @516 'P' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x00, 0xE0, /* ### */ + + /* @528 'Q' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x30, 0x10, /* ## # */ + 0x48, 0x20, /* # # # */ + 0x07, 0xC0, /* ##### */ + + /* @542 'R' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x03, 0x10, /* ## # */ + 0x0C, 0xE0, /* ## ### */ + 0x10, 0x00, /* # */ + + /* @556 'S' (6 pixels wide) */ + 0x08, 0xE0, /* # ### */ + 0x11, 0x90, /* # ## # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0x20, /* ### # */ + + /* @568 'T' (7 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + + /* @582 'U' (7 pixels wide) */ + 0x0F, 0xF0, /* ######## */ + 0x18, 0x00, /* ## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x0F, 0xF0, /* ######## */ + + /* @596 'V' (8 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x01, 0xC0, /* ### */ + 0x06, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x01, 0xC0, /* ### */ + 0x00, 0x30, /* ## */ + + /* @612 'W' (11 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0xE0, /* ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x80, /* #### */ + 0x00, 0x70, /* ### */ + 0x07, 0x80, /* #### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x10, /* # */ + + /* @634 'X' (7 pixels wide) */ + 0x10, 0x10, /* # # */ + 0x08, 0x30, /* # ## */ + 0x06, 0xC0, /* ## ## */ + 0x01, 0x00, /* # */ + 0x06, 0xC0, /* ## ## */ + 0x08, 0x30, /* # ## */ + 0x10, 0x10, /* # # */ + + /* @648 'Y' (7 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x60, /* ## */ + 0x01, 0x80, /* ## */ + 0x1E, 0x00, /* #### */ + 0x01, 0x80, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x10, /* # */ + + /* @662 'Z' (7 pixels wide) */ + 0x18, 0x10, /* ## # */ + 0x14, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x50, /* # # # */ + 0x10, 0x30, /* # ## */ + + /* @676 '[' (2 pixels wide) */ + 0x7F, 0xF0, /* ########### */ + 0x40, 0x10, /* # # */ + + /* @680 '\' (4 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x01, 0xC0, /* ### */ + 0x0E, 0x00, /* ### */ + 0x30, 0x00, /* ## */ + + /* @688 ']' (2 pixels wide) */ + 0x40, 0x10, /* # # */ + 0x7F, 0xF0, /* ########### */ + + /* @692 '^' (6 pixels wide) */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x40, /* # */ + + /* @704 '_' (6 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + + /* @716 '`' (2 pixels wide) */ + 0x00, 0x08, /* # */ + 0x00, 0x10, /* # */ + + /* @720 'a' (6 pixels wide) */ + 0x0C, 0x80, /* ## # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x0A, 0x40, /* # # # */ + 0x1F, 0x80, /* ###### */ + + /* @732 'b' (6 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0x0F, 0x80, /* ##### */ + + /* @744 'c' (5 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x08, 0x80, /* # # */ + + /* @754 'd' (6 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0x1F, 0xF8, /* ########## */ + + /* @766 'e' (6 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x0A, 0xC0, /* # # ## */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0xC0, /* # # ## */ + 0x0B, 0x80, /* # ### */ + + /* @778 'f' (4 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x48, /* # # */ + 0x00, 0x48, /* # # */ + + /* @786 'g' (6 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x58, 0xC0, /* # ## ## */ + 0x90, 0x40, /* # # # */ + 0x90, 0x40, /* # # # */ + 0xD8, 0xC0, /* ## ## ## */ + 0x7F, 0xC0, /* ######### */ + + /* @798 'h' (6 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + + /* @810 'i' (1 pixels wide) */ + 0x1F, 0xD0, /* ####### # */ + + /* @812 'j' (2 pixels wide) */ + 0x80, 0x00, /* # */ + 0xFF, 0xD0, /* ########## # */ + + /* @816 'k' (5 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x02, 0x00, /* # */ + 0x05, 0x00, /* # # */ + 0x08, 0x80, /* # # */ + 0x10, 0x40, /* # # */ + + /* @826 'l' (1 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + + /* @828 'm' (9 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + + /* @846 'n' (6 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + + /* @858 'o' (6 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0x0F, 0x80, /* ##### */ + + /* @870 'p' (6 pixels wide) */ + 0xFF, 0xC0, /* ########## */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0x0F, 0x80, /* ##### */ + + /* @882 'q' (6 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0xFF, 0xC0, /* ########## */ + + /* @894 'r' (4 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + + /* @902 's' (5 pixels wide) */ + 0x09, 0x80, /* # ## */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x0C, 0x80, /* ## # */ + + /* @912 't' (4 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + + /* @920 'u' (6 pixels wide) */ + 0x0F, 0xC0, /* ###### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + + /* @932 'v' (6 pixels wide) */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + + /* @944 'w' (9 pixels wide) */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + + /* @962 'x' (6 pixels wide) */ + 0x10, 0x40, /* # # */ + 0x0D, 0x80, /* ## ## */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x0D, 0x80, /* ## ## */ + 0x10, 0x40, /* # # */ + + /* @974 'y' (6 pixels wide) */ + 0x80, 0xC0, /* # ## */ + 0x83, 0x00, /* # ## */ + 0x4C, 0x00, /* # ## */ + 0x38, 0x00, /* ### */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + + /* @986 'z' (5 pixels wide) */ + 0x18, 0x40, /* ## # */ + 0x14, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x11, 0x40, /* # # # */ + 0x10, 0xC0, /* # ## */ + + /* @996 '{' (5 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x7D, 0xF0, /* ##### ##### */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + + /* @1006 '|' (1 pixels wide) */ + 0xFF, 0xF0, /* ############ */ + + /* @1008 '}' (5 pixels wide) */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + 0x7D, 0xF0, /* ##### ##### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @1018 '~' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x01, 0x00, /* # */ +}; + +/* Character descriptors for DejaVu Sans 9pt */ +/* { [Char width in bits], [Offset into dejaVuSans9ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dejaVuSans9ptCharDescriptors[] = +{ + {5, 0}, /* */ + {1, 10}, /* ! */ + {3, 12}, /* " */ + {8, 18}, /* # */ + {5, 34}, /* $ */ + {10, 44}, /* % */ + {8, 64}, /* & */ + {1, 80}, /* ' */ + {3, 82}, /* ( */ + {3, 88}, /* ) */ + {5, 94}, /* * */ + {7, 104}, /* + */ + {1, 118}, /* , */ + {3, 120}, /* - */ + {1, 126}, /* . */ + {4, 128}, /* / */ + {6, 136}, /* 0 */ + {5, 148}, /* 1 */ + {6, 158}, /* 2 */ + {6, 170}, /* 3 */ + {6, 182}, /* 4 */ + {6, 194}, /* 5 */ + {6, 206}, /* 6 */ + {6, 218}, /* 7 */ + {6, 230}, /* 8 */ + {6, 242}, /* 9 */ + {1, 254}, /* : */ + {1, 256}, /* ; */ + {8, 258}, /* < */ + {8, 274}, /* = */ + {8, 290}, /* > */ + {5, 306}, /* ? */ + {11, 316}, /* @ */ + {8, 338}, /* A */ + {6, 354}, /* B */ + {6, 366}, /* C */ + {7, 378}, /* D */ + {6, 392}, /* E */ + {5, 404}, /* F */ + {7, 414}, /* G */ + {7, 428}, /* H */ + {1, 442}, /* I */ + {3, 444}, /* J */ + {6, 450}, /* K */ + {5, 462}, /* L */ + {8, 472}, /* M */ + {7, 488}, /* N */ + {7, 502}, /* O */ + {6, 516}, /* P */ + {7, 528}, /* Q */ + {7, 542}, /* R */ + {6, 556}, /* S */ + {7, 568}, /* T */ + {7, 582}, /* U */ + {8, 596}, /* V */ + {11, 612}, /* W */ + {7, 634}, /* X */ + {7, 648}, /* Y */ + {7, 662}, /* Z */ + {2, 676}, /* [ */ + {4, 680}, /* \ */ + {2, 688}, /* ] */ + {6, 692}, /* ^ */ + {6, 704}, /* _ */ + {2, 716}, /* ` */ + {6, 720}, /* a */ + {6, 732}, /* b */ + {5, 744}, /* c */ + {6, 754}, /* d */ + {6, 766}, /* e */ + {4, 778}, /* f */ + {6, 786}, /* g */ + {6, 798}, /* h */ + {1, 810}, /* i */ + {2, 812}, /* j */ + {5, 816}, /* k */ + {1, 826}, /* l */ + {9, 828}, /* m */ + {6, 846}, /* n */ + {6, 858}, /* o */ + {6, 870}, /* p */ + {6, 882}, /* q */ + {4, 894}, /* r */ + {5, 902}, /* s */ + {4, 912}, /* t */ + {6, 920}, /* u */ + {6, 932}, /* v */ + {9, 944}, /* w */ + {6, 962}, /* x */ + {6, 974}, /* y */ + {5, 986}, /* z */ + {5, 996}, /* { */ + {1, 1006}, /* | */ + {5, 1008}, /* } */ + {8, 1018}, /* ~ */ +}; + +/* Font information for DejaVu Sans 9pt */ +const FONT_INFO dejaVuSans9ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + dejaVuSans9ptCharDescriptors, /* Character decriptor array */ + dejaVuSans9ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/dejavusans9.h b/drivers/lcd/tft/fonts/dejavusans9.h new file mode 100644 index 0000000..c5f4af0 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusans9.h @@ -0,0 +1,10 @@ +#ifndef __DEJA_VU_SANS_9__ +#define __DEJA_VU_SANS_9__ + +#include "bitmapfonts.h" + +extern const uint8_t dejaVuSans9ptCharBitmaps[]; +extern const FONT_CHAR_INFO dejaVuSans9ptCharDescriptors[]; +extern const FONT_INFO dejaVuSans9ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/dejavusansbold9.c b/drivers/lcd/tft/fonts/dejavusansbold9.c new file mode 100644 index 0000000..2164903 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansbold9.c @@ -0,0 +1,913 @@ +#include "dejavusansbold9.h" + +/* +** Font data for DejaVu Sans Bold 9pt +*/ + +/* Character bitmaps for DejaVu Sans Bold 9pt */ +const uint8_t dejaVuSansBold9ptCharBitmaps[] = +{ + /* @0 ' ' (5 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @10 '!' (2 pixels wide) */ + 0x1B, 0xF0, /* ## ###### */ + 0x1B, 0xF0, /* ## ###### */ + + /* @14 '"' (3 pixels wide) */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + + /* @20 '#' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x1E, 0x40, /* #### # */ + 0x0F, 0xC0, /* ###### */ + 0x02, 0x70, /* # ### */ + 0x1E, 0x40, /* #### # */ + 0x03, 0xE0, /* ##### */ + 0x02, 0x70, /* # ### */ + 0x00, 0x40, /* # */ + + /* @36 '$' (7 pixels wide) */ + 0x11, 0xC0, /* # ### */ + 0x13, 0xE0, /* # ##### */ + 0x13, 0xA0, /* # ### # */ + 0x7F, 0xF0, /* ########### */ + 0x17, 0x20, /* # ### # */ + 0x1F, 0x20, /* ##### # */ + 0x0E, 0x00, /* ### */ + + /* @50 '%' (11 pixels wide) */ + 0x00, 0xE0, /* ### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x19, 0x10, /* ## # # */ + 0x06, 0xE0, /* ## ### */ + 0x03, 0x80, /* ### */ + 0x0E, 0xC0, /* ### ## */ + 0x11, 0x30, /* # # ## */ + 0x11, 0x00, /* # # */ + 0x11, 0x00, /* # # */ + 0x0E, 0x00, /* ### */ + + /* @72 '&' (9 pixels wide) */ + 0x0E, 0x00, /* ### */ + 0x1F, 0x60, /* ##### ## */ + 0x11, 0xF0, /* # ##### */ + 0x13, 0x90, /* # ### # */ + 0x17, 0x10, /* # ### # */ + 0x1E, 0x20, /* #### # */ + 0x0C, 0x00, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x13, 0x00, /* # ## */ + + /* @90 ''' (1 pixels wide) */ + 0x00, 0x70, /* ### */ + + /* @92 '(' (4 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x3F, 0xF8, /* ########### */ + 0x38, 0x38, /* ### ### */ + 0x20, 0x08, /* # # */ + + /* @100 ')' (4 pixels wide) */ + 0x20, 0x08, /* # # */ + 0x38, 0x38, /* ### ### */ + 0x3F, 0xF8, /* ########### */ + 0x07, 0xC0, /* ##### */ + + /* @108 '*' (5 pixels wide) */ + 0x01, 0x20, /* # # */ + 0x00, 0xC0, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + + /* @118 '+' (7 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @132 ',' (3 pixels wide) */ + 0x40, 0x00, /* # */ + 0x38, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + + /* @138 '-' (4 pixels wide) */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + + /* @146 '.' (2 pixels wide) */ + 0x18, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + + /* @150 '/' (4 pixels wide) */ + 0x30, 0x00, /* ## */ + 0x1E, 0x00, /* #### */ + 0x01, 0xE0, /* #### */ + 0x00, 0x30, /* ## */ + + /* @158 '0' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xC0, /* ##### */ + + /* @172 '1' (6 pixels wide) */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @184 '2' (7 pixels wide) */ + 0x10, 0x20, /* # # */ + 0x18, 0x10, /* ## # */ + 0x1C, 0x10, /* ### # */ + 0x16, 0x10, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x11, 0xF0, /* # ##### */ + 0x10, 0xE0, /* # ### */ + + /* @198 '3' (7 pixels wide) */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1F, 0xF0, /* ######### */ + 0x0E, 0xE0, /* ### ### */ + + /* @212 '4' (7 pixels wide) */ + 0x07, 0x00, /* ### */ + 0x05, 0x80, /* # ## */ + 0x04, 0x60, /* # ## */ + 0x04, 0x30, /* # ## */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x04, 0x00, /* # */ + + /* @226 '5' (7 pixels wide) */ + 0x10, 0xF0, /* # #### */ + 0x10, 0xF0, /* # #### */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x90, /* ## ## # */ + 0x1F, 0x90, /* ###### # */ + 0x0F, 0x00, /* #### */ + + /* @240 '6' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x10, 0xB0, /* # # ## */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x1F, 0x90, /* ###### # */ + 0x0F, 0x00, /* #### */ + + /* @254 '7' (7 pixels wide) */ + 0x00, 0x10, /* # */ + 0x10, 0x10, /* # # */ + 0x1C, 0x10, /* ### # */ + 0x0F, 0x10, /* #### # */ + 0x03, 0xD0, /* #### # */ + 0x00, 0xF0, /* #### */ + 0x00, 0x30, /* ## */ + + /* @268 '8' (7 pixels wide) */ + 0x0E, 0xE0, /* ### ### */ + 0x1E, 0xF0, /* #### #### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1E, 0xF0, /* #### #### */ + 0x0E, 0xE0, /* ### ### */ + + /* @282 '9' (7 pixels wide) */ + 0x01, 0xE0, /* #### */ + 0x13, 0xF0, /* # ###### */ + 0x12, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x1A, 0x10, /* ## # # */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xC0, /* ##### */ + + /* @296 ':' (2 pixels wide) */ + 0x18, 0xC0, /* ## ## */ + 0x18, 0xC0, /* ## ## */ + + /* @300 ';' (3 pixels wide) */ + 0x40, 0x00, /* # */ + 0x38, 0xC0, /* ### ## */ + 0x18, 0xC0, /* ## ## */ + + /* @306 '<' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x07, 0x00, /* ### */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x0D, 0x80, /* ## ## */ + 0x08, 0x80, /* # # */ + 0x08, 0x80, /* # # */ + 0x18, 0xC0, /* ## ## */ + + /* @322 '=' (8 pixels wide) */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + + /* @338 '>' (8 pixels wide) */ + 0x18, 0xC0, /* ## ## */ + 0x08, 0x80, /* # # */ + 0x08, 0x80, /* # # */ + 0x0D, 0x80, /* ## ## */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x07, 0x00, /* ### */ + 0x02, 0x00, /* # */ + + /* @354 '?' (5 pixels wide) */ + 0x00, 0x10, /* # */ + 0x1B, 0x10, /* ## ## # */ + 0x1B, 0x90, /* ## ### # */ + 0x00, 0xF0, /* #### */ + 0x00, 0x60, /* ## */ + + /* @364 '@' (10 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x20, 0x20, /* # # */ + 0x47, 0x10, /* # ### # */ + 0x48, 0x90, /* # # # # */ + 0x48, 0x90, /* # # # # */ + 0x4F, 0x90, /* # ##### # */ + 0x68, 0x20, /* ## # # */ + 0x0C, 0x60, /* ## ## */ + 0x07, 0x80, /* #### */ + + /* @384 'A' (9 pixels wide) */ + 0x10, 0x00, /* # */ + 0x1E, 0x00, /* #### */ + 0x0F, 0xC0, /* ###### */ + 0x05, 0xF0, /* # ##### */ + 0x04, 0x30, /* # ## */ + 0x05, 0xF0, /* # ##### */ + 0x0F, 0xC0, /* ###### */ + 0x1E, 0x00, /* #### */ + 0x10, 0x00, /* # */ + + /* @402 'B' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1F, 0xF0, /* ######### */ + 0x0E, 0xE0, /* ### ### */ + + /* @416 'C' (7 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + + /* @430 'D' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xC0, /* ##### */ + + /* @446 'E' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + + /* @458 'F' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + + /* @470 'G' (8 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x1F, 0x10, /* ##### # */ + 0x1F, 0x30, /* ##### ## */ + + /* @486 'H' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + + /* @502 'I' (2 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + + /* @506 'J' (4 pixels wide) */ + 0x40, 0x00, /* # */ + 0x40, 0x00, /* # */ + 0x7F, 0xF0, /* ########### */ + 0x3F, 0xF0, /* ########## */ + + /* @514 'K' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x03, 0x80, /* ### */ + 0x06, 0xC0, /* ## ## */ + 0x0C, 0x60, /* ## ## */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + + /* @530 'L' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @542 'M' (10 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x70, /* ### */ + 0x01, 0xC0, /* ### */ + 0x07, 0x00, /* ### */ + 0x07, 0x00, /* ### */ + 0x01, 0xC0, /* ### */ + 0x00, 0x70, /* ### */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + + /* @562 'N' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x70, /* ### */ + 0x01, 0xC0, /* ### */ + 0x07, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + + /* @578 'O' (9 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xC0, /* ##### */ + + /* @596 'P' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x02, 0x10, /* # # */ + 0x02, 0x10, /* # # */ + 0x02, 0x10, /* # # */ + 0x03, 0xF0, /* ###### */ + 0x01, 0xE0, /* #### */ + + /* @610 'Q' (9 pixels wide) */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x30, 0x10, /* ## # */ + 0x78, 0x30, /* #### ## */ + 0x4F, 0xE0, /* # ####### */ + 0x07, 0xC0, /* ##### */ + + /* @628 'R' (8 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x03, 0x10, /* ## # */ + 0x0F, 0xF0, /* ######## */ + 0x1C, 0xE0, /* ### ### */ + 0x10, 0x00, /* # */ + + /* @644 'S' (7 pixels wide) */ + 0x18, 0xE0, /* ## ### */ + 0x11, 0xF0, /* # ##### */ + 0x11, 0x90, /* # ## # */ + 0x11, 0x90, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x1F, 0x30, /* ##### ## */ + 0x0E, 0x00, /* ### */ + + /* @658 'T' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + + /* @674 'U' (8 pixels wide) */ + 0x0F, 0xF0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x0F, 0xF0, /* ######## */ + + /* @690 'V' (9 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0xF0, /* #### */ + 0x07, 0xE0, /* ###### */ + 0x1F, 0x00, /* ##### */ + 0x18, 0x00, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x07, 0xE0, /* ###### */ + 0x00, 0xF0, /* #### */ + 0x00, 0x10, /* # */ + + /* @708 'W' (12 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x1F, 0xC0, /* ####### */ + 0x1E, 0x00, /* #### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0xF0, /* #### */ + 0x00, 0xF0, /* #### */ + 0x07, 0xC0, /* ##### */ + 0x1E, 0x00, /* #### */ + 0x1F, 0xC0, /* ####### */ + 0x03, 0xF0, /* ###### */ + 0x00, 0x30, /* ## */ + + /* @732 'X' (9 pixels wide) */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x0E, 0xE0, /* ### ### */ + 0x07, 0xC0, /* ##### */ + 0x01, 0x00, /* # */ + 0x07, 0xC0, /* ##### */ + 0x0E, 0xE0, /* ### ### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + + /* @750 'Y' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x70, /* ### */ + 0x00, 0xE0, /* ### */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x70, /* ### */ + 0x00, 0x10, /* # */ + + /* @766 'Z' (8 pixels wide) */ + 0x18, 0x10, /* ## # */ + 0x1C, 0x10, /* ### # */ + 0x16, 0x10, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x11, 0x90, /* # ## # */ + 0x10, 0xD0, /* # ## # */ + 0x10, 0x70, /* # ### */ + 0x10, 0x30, /* # ## */ + + /* @782 '[' (4 pixels wide) */ + 0x3F, 0xF8, /* ########### */ + 0x3F, 0xF8, /* ########### */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + + /* @790 '\' (4 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x01, 0xE0, /* #### */ + 0x1E, 0x00, /* #### */ + 0x30, 0x00, /* ## */ + + /* @798 ']' (4 pixels wide) */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x3F, 0xF8, /* ########### */ + 0x3F, 0xF8, /* ########### */ + + /* @806 '^' (6 pixels wide) */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x30, /* ## */ + 0x00, 0x30, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x40, /* # */ + + /* @818 '_' (6 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + + /* @830 '`' (3 pixels wide) */ + 0x00, 0x08, /* # */ + 0x00, 0x18, /* ## */ + 0x00, 0x10, /* # */ + + /* @836 'a' (7 pixels wide) */ + 0x0C, 0x00, /* ## */ + 0x1E, 0x80, /* #### # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x1A, 0x40, /* ## # # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + + /* @850 'b' (7 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + + /* @864 'c' (6 pixels wide) */ + 0x07, 0x00, /* ### */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x08, 0x80, /* # # */ + + /* @876 'd' (7 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + + /* @890 'e' (7 pixels wide) */ + 0x07, 0x00, /* ### */ + 0x0F, 0x80, /* ##### */ + 0x1A, 0xC0, /* ## # ## */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x13, 0xC0, /* # #### */ + 0x0B, 0x00, /* # ## */ + + /* @904 'f' (5 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x48, /* # # */ + 0x00, 0x48, /* # # */ + + /* @914 'g' (7 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x5F, 0xC0, /* # ####### */ + 0x90, 0xC0, /* # # ## */ + 0x90, 0x40, /* # # # */ + 0x90, 0x40, /* # # # */ + 0xFF, 0xC0, /* ########## */ + 0x7F, 0xC0, /* ######### */ + + /* @928 'h' (7 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0xC0, /* ## */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + + /* @942 'i' (2 pixels wide) */ + 0x1F, 0xD8, /* ####### ## */ + 0x1F, 0xD8, /* ####### ## */ + + /* @946 'j' (3 pixels wide) */ + 0x80, 0x00, /* # */ + 0xFF, 0xD8, /* ########## ## */ + 0x7F, 0xD8, /* ######### ## */ + + /* @952 'k' (7 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x03, 0x00, /* ## */ + 0x07, 0x80, /* #### */ + 0x0C, 0xC0, /* ## ## */ + 0x18, 0x40, /* ## # */ + 0x10, 0x00, /* # */ + + /* @966 'l' (2 pixels wide) */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + + /* @970 'm' (10 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + + /* @990 'n' (7 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + + /* @1004 'o' (7 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + + /* @1018 'p' (7 pixels wide) */ + 0xFF, 0xC0, /* ########## */ + 0xFF, 0xC0, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + + /* @1032 'q' (7 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0xFF, 0xC0, /* ########## */ + 0xFF, 0xC0, /* ########## */ + + /* @1046 'r' (5 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + + /* @1056 's' (6 pixels wide) */ + 0x09, 0x80, /* # ## */ + 0x13, 0xC0, /* # #### */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x1E, 0x40, /* #### # */ + 0x0C, 0x80, /* ## # */ + + /* @1068 't' (5 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + + /* @1078 'u' (7 pixels wide) */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + + /* @1092 'v' (7 pixels wide) */ + 0x00, 0xC0, /* ## */ + 0x07, 0xC0, /* ##### */ + 0x1F, 0x00, /* ##### */ + 0x18, 0x00, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0xC0, /* ## */ + + /* @1106 'w' (10 pixels wide) */ + 0x01, 0xC0, /* ### */ + 0x0F, 0xC0, /* ###### */ + 0x1C, 0x00, /* ### */ + 0x1F, 0x00, /* ##### */ + 0x03, 0xC0, /* #### */ + 0x03, 0xC0, /* #### */ + 0x1F, 0x00, /* ##### */ + 0x1C, 0x00, /* ### */ + 0x0F, 0xC0, /* ###### */ + 0x01, 0xC0, /* ### */ + + /* @1126 'x' (7 pixels wide) */ + 0x10, 0x40, /* # # */ + 0x18, 0xC0, /* ## ## */ + 0x0F, 0x80, /* ##### */ + 0x07, 0x00, /* ### */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + + /* @1140 'y' (7 pixels wide) */ + 0x00, 0xC0, /* ## */ + 0x83, 0xC0, /* # #### */ + 0xCF, 0x00, /* ## #### */ + 0x7C, 0x00, /* ##### */ + 0x3F, 0x00, /* ###### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0xC0, /* ## */ + + /* @1154 'z' (6 pixels wide) */ + 0x18, 0x40, /* ## # */ + 0x1C, 0x40, /* ### # */ + 0x16, 0x40, /* # ## # */ + 0x13, 0x40, /* # ## # */ + 0x11, 0xC0, /* # ### */ + 0x10, 0xC0, /* # ## */ + + /* @1166 '{' (6 pixels wide) */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x3E, 0xF8, /* ##### ##### */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + + /* @1178 '|' (1 pixels wide) */ + 0xFF, 0xF0, /* ############ */ + + /* @1180 '}' (6 pixels wide) */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x3E, 0xF8, /* ##### ##### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + + /* @1192 '~' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x01, 0x00, /* # */ +}; + +/* Character descriptors for DejaVu Sans 9pt */ +/* { [Char width in bits], [Offset into dejaVuSansBold9ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dejaVuSansBold9ptCharDescriptors[] = +{ + {5, 0}, /* */ + {2, 10}, /* ! */ + {3, 14}, /* " */ + {8, 20}, /* # */ + {7, 36}, /* $ */ + {11, 50}, /* % */ + {9, 72}, /* & */ + {1, 90}, /* ' */ + {4, 92}, /* ( */ + {4, 100}, /* ) */ + {5, 108}, /* * */ + {7, 118}, /* + */ + {3, 132}, /* , */ + {4, 138}, /* - */ + {2, 146}, /* . */ + {4, 150}, /* / */ + {7, 158}, /* 0 */ + {6, 172}, /* 1 */ + {7, 184}, /* 2 */ + {7, 198}, /* 3 */ + {7, 212}, /* 4 */ + {7, 226}, /* 5 */ + {7, 240}, /* 6 */ + {7, 254}, /* 7 */ + {7, 268}, /* 8 */ + {7, 282}, /* 9 */ + {2, 296}, /* : */ + {3, 300}, /* ; */ + {8, 306}, /* < */ + {8, 322}, /* = */ + {8, 338}, /* > */ + {5, 354}, /* ? */ + {10, 364}, /* @ */ + {9, 384}, /* A */ + {7, 402}, /* B */ + {7, 416}, /* C */ + {8, 430}, /* D */ + {6, 446}, /* E */ + {6, 458}, /* F */ + {8, 470}, /* G */ + {8, 486}, /* H */ + {2, 502}, /* I */ + {4, 506}, /* J */ + {8, 514}, /* K */ + {6, 530}, /* L */ + {10, 542}, /* M */ + {8, 562}, /* N */ + {9, 578}, /* O */ + {7, 596}, /* P */ + {9, 610}, /* Q */ + {8, 628}, /* R */ + {7, 644}, /* S */ + {8, 658}, /* T */ + {8, 674}, /* U */ + {9, 690}, /* V */ + {12, 708}, /* W */ + {9, 732}, /* X */ + {8, 750}, /* Y */ + {8, 766}, /* Z */ + {4, 782}, /* [ */ + {4, 790}, /* \ */ + {4, 798}, /* ] */ + {6, 806}, /* ^ */ + {6, 818}, /* _ */ + {3, 830}, /* ` */ + {7, 836}, /* a */ + {7, 850}, /* b */ + {6, 864}, /* c */ + {7, 876}, /* d */ + {7, 890}, /* e */ + {5, 904}, /* f */ + {7, 914}, /* g */ + {7, 928}, /* h */ + {2, 942}, /* i */ + {3, 946}, /* j */ + {7, 952}, /* k */ + {2, 966}, /* l */ + {10, 970}, /* m */ + {7, 990}, /* n */ + {7, 1004}, /* o */ + {7, 1018}, /* p */ + {7, 1032}, /* q */ + {5, 1046}, /* r */ + {6, 1056}, /* s */ + {5, 1068}, /* t */ + {7, 1078}, /* u */ + {7, 1092}, /* v */ + {10, 1106}, /* w */ + {7, 1126}, /* x */ + {7, 1140}, /* y */ + {6, 1154}, /* z */ + {6, 1166}, /* { */ + {1, 1178}, /* | */ + {6, 1180}, /* } */ + {8, 1192}, /* ~ */ +}; + +/* Font information for DejaVu Sans 9pt */ +const FONT_INFO dejaVuSansBold9ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + dejaVuSansBold9ptCharDescriptors, /* Character decriptor array */ + dejaVuSansBold9ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/dejavusansbold9.h b/drivers/lcd/tft/fonts/dejavusansbold9.h new file mode 100644 index 0000000..d4b6490 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansbold9.h @@ -0,0 +1,10 @@ +#ifndef __DEJA_VU_SANS_BOLD_9__ +#define __DEJA_VU_SANS_BOLD_9__ + +#include "bitmapfonts.h" + +extern const uint8_t dejaVuSansBold9ptCharBitmaps[]; +extern const FONT_CHAR_INFO dejaVuSansBold9ptCharDescriptors[]; +extern const FONT_INFO dejaVuSansBold9ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/dejavusanscondensed9.c b/drivers/lcd/tft/fonts/dejavusanscondensed9.c new file mode 100644 index 0000000..204ca28 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusanscondensed9.c @@ -0,0 +1,774 @@ +#include "dejavusanscondensed9.h" + +/* +** Font data for DejaVu Sans Condensed 9pt +*/ + +/* Character bitmaps for DejaVu Sans Condensed 9pt */ +const uint8_t dejaVuSansCondensed9ptCharBitmaps[] = +{ + /* @0 ' ' (5 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @10 '!' (1 pixels wide) */ + 0x13, 0xF0, /* # ###### */ + + /* @12 '"' (3 pixels wide) */ + 0x00, 0xF0, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0xF0, /* #### */ + + /* @18 '#' (7 pixels wide) */ + 0x04, 0x80, /* # # */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xE0, /* ###### */ + 0x14, 0x90, /* # # # # */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xF0, /* # #### */ + 0x04, 0x80, /* # # */ + + /* @32 '$' (5 pixels wide) */ + 0x11, 0xC0, /* # ### */ + 0x11, 0x20, /* # # # */ + 0x7F, 0xF0, /* ########### */ + 0x12, 0x20, /* # # # */ + 0x0E, 0x40, /* ### # */ + + /* @42 '%' (9 pixels wide) */ + 0x01, 0xF0, /* ##### */ + 0x11, 0x10, /* # # # */ + 0x08, 0xF0, /* # #### */ + 0x06, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x0E, 0x60, /* ### ## */ + 0x11, 0x10, /* # # # */ + 0x12, 0x00, /* # # */ + 0x0C, 0x00, /* ## */ + + /* @60 '&' (7 pixels wide) */ + 0x0F, 0x00, /* #### */ + 0x10, 0xF0, /* # #### */ + 0x11, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x1C, 0x00, /* ### */ + 0x1E, 0x00, /* #### */ + 0x11, 0x00, /* # # */ + + /* @74 ''' (1 pixels wide) */ + 0x00, 0xF0, /* #### */ + + /* @76 '(' (2 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x60, 0x30, /* ## ## */ + + /* @80 ')' (2 pixels wide) */ + 0x60, 0x10, /* ## # */ + 0x1F, 0xE0, /* ######## */ + + /* @84 '*' (5 pixels wide) */ + 0x00, 0x20, /* # */ + 0x00, 0xC0, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + + /* @94 '+' (7 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @108 ',' (1 pixels wide) */ + 0x30, 0x00, /* ## */ + + /* @110 '-' (2 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @114 '.' (1 pixels wide) */ + 0x10, 0x00, /* # */ + + /* @116 '/' (4 pixels wide) */ + 0x30, 0x00, /* ## */ + 0x0F, 0x00, /* #### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x10, /* # */ + + /* @124 '0' (5 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x30, /* # ## */ + 0x0F, 0xE0, /* ####### */ + + /* @134 '1' (5 pixels wide) */ + 0x10, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @144 '2' (5 pixels wide) */ + 0x18, 0x30, /* ## ## */ + 0x1C, 0x10, /* ### # */ + 0x12, 0x10, /* # # # */ + 0x11, 0xB0, /* # ## ## */ + 0x10, 0xE0, /* # ### */ + + /* @154 '3' (5 pixels wide) */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0xB0, /* # ## ## */ + 0x0E, 0xE0, /* ### ### */ + + /* @164 '4' (5 pixels wide) */ + 0x07, 0x00, /* ### */ + 0x04, 0xC0, /* # ## */ + 0x04, 0x20, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x04, 0x00, /* # */ + + /* @174 '5' (5 pixels wide) */ + 0x10, 0xF0, /* # #### */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x10, /* ## # # */ + 0x0F, 0x00, /* #### */ + + /* @184 '6' (5 pixels wide) */ + 0x0F, 0xC0, /* ###### */ + 0x11, 0x20, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x0F, 0x10, /* #### # */ + + /* @194 '7' (5 pixels wide) */ + 0x00, 0x10, /* # */ + 0x10, 0x10, /* # # */ + 0x0E, 0x10, /* ### # */ + 0x01, 0xD0, /* ### # */ + 0x00, 0x30, /* ## */ + + /* @204 '8' (5 pixels wide) */ + 0x1E, 0xE0, /* #### ### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + + /* @214 '9' (5 pixels wide) */ + 0x11, 0xE0, /* # #### */ + 0x12, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x1B, 0x30, /* ## ## ## */ + 0x0F, 0xE0, /* ####### */ + + /* @224 ':' (1 pixels wide) */ + 0x10, 0x80, /* # # */ + + /* @226 ';' (1 pixels wide) */ + 0x30, 0x80, /* ## # */ + + /* @228 '<' (7 pixels wide) */ + 0x02, 0x00, /* # */ + 0x03, 0x00, /* ## */ + 0x05, 0x00, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x08, 0x80, /* # # */ + 0x08, 0x40, /* # # */ + + /* @242 '=' (7 pixels wide) */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + + /* @256 '>' (7 pixels wide) */ + 0x08, 0x40, /* # # */ + 0x08, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x05, 0x00, /* # # */ + 0x03, 0x00, /* ## */ + 0x02, 0x00, /* # */ + + /* @270 '?' (4 pixels wide) */ + 0x00, 0x10, /* # */ + 0x17, 0x10, /* # ### # */ + 0x01, 0x90, /* ## # */ + 0x00, 0x60, /* ## */ + + /* @278 '@' (9 pixels wide) */ + 0x1F, 0x80, /* ###### */ + 0x20, 0x40, /* # # */ + 0x47, 0x20, /* # ### # */ + 0x48, 0xA0, /* # # # # */ + 0x50, 0xA0, /* # # # # */ + 0x49, 0x20, /* # # # # */ + 0x4F, 0xA0, /* # ##### # */ + 0x08, 0x40, /* # # */ + 0x07, 0x80, /* #### */ + + /* @296 'A' (7 pixels wide) */ + 0x10, 0x00, /* # */ + 0x0E, 0x00, /* ### */ + 0x05, 0xC0, /* # ### */ + 0x04, 0x30, /* # ## */ + 0x04, 0xE0, /* # ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + + /* @310 'B' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1B, 0xE0, /* ## ##### */ + 0x04, 0x00, /* # */ + + /* @322 'C' (6 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x20, /* ## # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x20, /* # # */ + + /* @334 'D' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x20, /* ## # */ + 0x0C, 0xE0, /* ## ### */ + 0x03, 0x80, /* ### */ + + /* @348 'E' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + + /* @358 'F' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x00, 0x10, /* # */ + + /* @368 'G' (6 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x20, /* ## # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x1F, 0x30, /* ##### ## */ + + /* @380 'H' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + + /* @392 'I' (1 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + + /* @394 'J' (3 pixels wide) */ + 0x40, 0x00, /* # */ + 0x40, 0x00, /* # */ + 0x7F, 0xF0, /* ########### */ + + /* @400 'K' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x02, 0x80, /* # # */ + 0x04, 0x60, /* # ## */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + + /* @412 'L' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + + /* @422 'M' (7 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x70, /* ### */ + 0x03, 0x80, /* ### */ + 0x04, 0x00, /* # */ + 0x03, 0x80, /* ### */ + 0x00, 0x60, /* ## */ + 0x1F, 0xF0, /* ######### */ + + /* @436 'N' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x70, /* ### */ + 0x01, 0xC0, /* ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x1F, 0xF0, /* ######### */ + + /* @448 'O' (7 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x20, /* ## # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x0C, 0x60, /* ## ## */ + 0x07, 0xC0, /* ##### */ + + /* @462 'P' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x02, 0x10, /* # # */ + 0x02, 0x10, /* # # */ + 0x01, 0x30, /* # ## */ + 0x01, 0xE0, /* #### */ + + /* @472 'Q' (7 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x20, /* ## # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x30, 0x10, /* ## # */ + 0x4C, 0x60, /* # ## ## */ + 0x07, 0xC0, /* ##### */ + + /* @486 'R' (6 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x03, 0x30, /* ## ## */ + 0x0E, 0xE0, /* ### ### */ + 0x18, 0x00, /* ## */ + + /* @498 'S' (5 pixels wide) */ + 0x10, 0xE0, /* # ### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1E, 0x30, /* #### ## */ + + /* @508 'T' (7 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + + /* @522 'U' (6 pixels wide) */ + 0x0F, 0xF0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x0F, 0xF0, /* ######## */ + + /* @534 'V' (7 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0xE0, /* ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x0E, 0x00, /* ### */ + 0x01, 0xC0, /* ### */ + 0x00, 0x70, /* ### */ + + /* @548 'W' (10 pixels wide) */ + 0x00, 0x10, /* # */ + 0x01, 0xE0, /* #### */ + 0x1E, 0x00, /* #### */ + 0x1E, 0x00, /* #### */ + 0x01, 0xE0, /* #### */ + 0x00, 0x70, /* ### */ + 0x07, 0x80, /* #### */ + 0x18, 0x00, /* ## */ + 0x0F, 0x00, /* #### */ + 0x00, 0xF0, /* #### */ + + /* @568 'X' (6 pixels wide) */ + 0x18, 0x30, /* ## ## */ + 0x06, 0x60, /* ## ## */ + 0x03, 0x80, /* ### */ + 0x06, 0xC0, /* ## ## */ + 0x0C, 0x60, /* ## ## */ + 0x10, 0x10, /* # # */ + + /* @580 'Y' (6 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x60, /* ## */ + 0x00, 0x80, /* # */ + 0x1F, 0x00, /* ##### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x30, /* ## */ + + /* @592 'Z' (7 pixels wide) */ + 0x10, 0x00, /* # */ + 0x18, 0x10, /* ## # */ + 0x16, 0x10, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x70, /* # ### */ + 0x10, 0x30, /* # ## */ + + /* @606 '[' (2 pixels wide) */ + 0x7F, 0xF0, /* ########### */ + 0x40, 0x10, /* # # */ + + /* @610 '\' (3 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x03, 0xC0, /* #### */ + 0x3C, 0x00, /* #### */ + + /* @616 ']' (2 pixels wide) */ + 0x40, 0x10, /* # # */ + 0x7F, 0xF0, /* ########### */ + + /* @620 '^' (7 pixels wide) */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x80, /* # */ + + /* @634 '_' (6 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + + /* @646 '`' (2 pixels wide) */ + 0x00, 0x08, /* # */ + 0x00, 0x10, /* # */ + + /* @650 'a' (5 pixels wide) */ + 0x1E, 0x80, /* #### # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x0A, 0x80, /* # # # */ + 0x1F, 0x00, /* ##### */ + + /* @660 'b' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x80, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x0F, 0x80, /* ##### */ + + /* @670 'c' (4 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x10, 0xC0, /* # ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + + /* @678 'd' (5 pixels wide) */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0xF0, /* ######### */ + + /* @688 'e' (5 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0xC0, /* # # ## */ + 0x13, 0x80, /* # ### */ + + /* @698 'f' (4 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x50, /* # # */ + 0x00, 0x50, /* # # */ + + /* @706 'g' (5 pixels wide) */ + 0x4F, 0x80, /* # ##### */ + 0x90, 0x40, /* # # # */ + 0x90, 0x40, /* # # # */ + 0x48, 0x80, /* # # # */ + 0x3F, 0xC0, /* ######## */ + + /* @716 'h' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x80, /* ###### */ + + /* @726 'i' (1 pixels wide) */ + 0x1F, 0xD0, /* ####### # */ + + /* @728 'j' (2 pixels wide) */ + 0x80, 0x00, /* # */ + 0x7F, 0xD0, /* ######### # */ + + /* @732 'k' (5 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + 0x02, 0x00, /* # */ + 0x05, 0x00, /* # # */ + 0x18, 0x80, /* ## # */ + 0x10, 0x40, /* # # */ + + /* @742 'l' (1 pixels wide) */ + 0x1F, 0xF0, /* ######### */ + + /* @744 'm' (9 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x00, /* ##### */ + + /* @762 'n' (5 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x80, /* ###### */ + + /* @772 'o' (5 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x80, /* # # */ + 0x0F, 0x80, /* ##### */ + + /* @782 'p' (5 pixels wide) */ + 0xFF, 0xC0, /* ########## */ + 0x10, 0x80, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x0F, 0x80, /* ##### */ + + /* @792 'q' (5 pixels wide) */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x80, /* # # */ + 0xFF, 0xC0, /* ########## */ + + /* @802 'r' (3 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + + /* @808 's' (4 pixels wide) */ + 0x13, 0x80, /* # ### */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x1C, 0x80, /* ### # */ + + /* @816 't' (4 pixels wide) */ + 0x00, 0x40, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + + /* @824 'u' (5 pixels wide) */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + + /* @834 'v' (6 pixels wide) */ + 0x00, 0x40, /* # */ + 0x03, 0x80, /* ### */ + 0x1C, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + + /* @846 'w' (8 pixels wide) */ + 0x00, 0x40, /* # */ + 0x07, 0x80, /* #### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x01, 0xC0, /* ### */ + 0x0E, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x03, 0xC0, /* #### */ + + /* @862 'x' (5 pixels wide) */ + 0x18, 0xC0, /* ## ## */ + 0x05, 0x00, /* # # */ + 0x07, 0x00, /* ### */ + 0x09, 0x80, /* # ## */ + 0x10, 0x40, /* # # */ + + /* @872 'y' (6 pixels wide) */ + 0x00, 0x40, /* # */ + 0x83, 0x80, /* # ### */ + 0x6C, 0x00, /* ## ## */ + 0x38, 0x00, /* ### */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + + /* @884 'z' (5 pixels wide) */ + 0x10, 0x00, /* # */ + 0x18, 0x40, /* ## # */ + 0x16, 0x40, /* # ## # */ + 0x13, 0x40, /* # ## # */ + 0x10, 0xC0, /* # ## */ + + /* @894 '{' (5 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x7D, 0xF0, /* ##### ##### */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + + /* @904 '|' (1 pixels wide) */ + 0xFF, 0xF0, /* ############ */ + + /* @906 '}' (5 pixels wide) */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + 0x3D, 0xF0, /* #### ##### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + + /* @916 '~' (7 pixels wide) */ + 0x02, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ +}; + +/* Character descriptors for DejaVu Sans Condensed 9pt */ +/* { [Char width in bits], [Offset into dejaVuSansCondensed9ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dejaVuSansCondensed9ptCharDescriptors[] = +{ + {5, 0}, /* */ + {1, 10}, /* ! */ + {3, 12}, /* " */ + {7, 18}, /* # */ + {5, 32}, /* $ */ + {9, 42}, /* % */ + {7, 60}, /* & */ + {1, 74}, /* ' */ + {2, 76}, /* ( */ + {2, 80}, /* ) */ + {5, 84}, /* * */ + {7, 94}, /* + */ + {1, 108}, /* , */ + {2, 110}, /* - */ + {1, 114}, /* . */ + {4, 116}, /* / */ + {5, 124}, /* 0 */ + {5, 134}, /* 1 */ + {5, 144}, /* 2 */ + {5, 154}, /* 3 */ + {5, 164}, /* 4 */ + {5, 174}, /* 5 */ + {5, 184}, /* 6 */ + {5, 194}, /* 7 */ + {5, 204}, /* 8 */ + {5, 214}, /* 9 */ + {1, 224}, /* : */ + {1, 226}, /* ; */ + {7, 228}, /* < */ + {7, 242}, /* = */ + {7, 256}, /* > */ + {4, 270}, /* ? */ + {9, 278}, /* @ */ + {7, 296}, /* A */ + {6, 310}, /* B */ + {6, 322}, /* C */ + {7, 334}, /* D */ + {5, 348}, /* E */ + {5, 358}, /* F */ + {6, 368}, /* G */ + {6, 380}, /* H */ + {1, 392}, /* I */ + {3, 394}, /* J */ + {6, 400}, /* K */ + {5, 412}, /* L */ + {7, 422}, /* M */ + {6, 436}, /* N */ + {7, 448}, /* O */ + {5, 462}, /* P */ + {7, 472}, /* Q */ + {6, 486}, /* R */ + {5, 498}, /* S */ + {7, 508}, /* T */ + {6, 522}, /* U */ + {7, 534}, /* V */ + {10, 548}, /* W */ + {6, 568}, /* X */ + {6, 580}, /* Y */ + {7, 592}, /* Z */ + {2, 606}, /* [ */ + {3, 610}, /* \ */ + {2, 616}, /* ] */ + {7, 620}, /* ^ */ + {6, 634}, /* _ */ + {2, 646}, /* ` */ + {5, 650}, /* a */ + {5, 660}, /* b */ + {4, 670}, /* c */ + {5, 678}, /* d */ + {5, 688}, /* e */ + {4, 698}, /* f */ + {5, 706}, /* g */ + {5, 716}, /* h */ + {1, 726}, /* i */ + {2, 728}, /* j */ + {5, 732}, /* k */ + {1, 742}, /* l */ + {9, 744}, /* m */ + {5, 762}, /* n */ + {5, 772}, /* o */ + {5, 782}, /* p */ + {5, 792}, /* q */ + {3, 802}, /* r */ + {4, 808}, /* s */ + {4, 816}, /* t */ + {5, 824}, /* u */ + {6, 834}, /* v */ + {8, 846}, /* w */ + {5, 862}, /* x */ + {6, 872}, /* y */ + {5, 884}, /* z */ + {5, 894}, /* { */ + {1, 904}, /* | */ + {5, 906}, /* } */ + {7, 916}, /* ~ */ +}; + +/* Font information for DejaVu Sans Condensed 9pt */ +const FONT_INFO dejaVuSansCondensed9ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + dejaVuSansCondensed9ptCharDescriptors, /* Character decriptor array */ + dejaVuSansCondensed9ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/dejavusanscondensed9.h b/drivers/lcd/tft/fonts/dejavusanscondensed9.h new file mode 100644 index 0000000..a07c51f --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusanscondensed9.h @@ -0,0 +1,10 @@ +#ifndef __DEJA_VU_SANS_CONDENSED_9__ +#define __DEJA_VU_SANS_CONDENSED_9__ + +#include "bitmapfonts.h" + +extern const uint8_t dejaVuSansCondensed9ptCharBitmaps[]; +extern const FONT_CHAR_INFO dejaVuSansCondensed9ptCharDescriptors[]; +extern const FONT_INFO dejaVuSansCondensed9ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/dejavusansmono8.c b/drivers/lcd/tft/fonts/dejavusansmono8.c new file mode 100644 index 0000000..cf758ee --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansmono8.c @@ -0,0 +1,1069 @@ +#include "dejavusansmono8.h" + +/* +** Font data for DejaVu Sans Mono 8pt +*/ + +/* Character bitmaps for DejaVu Sans Mono 8pt */ +const uint8_t dejaVuSansMono8ptCharBitmaps[] = +{ + /* @0 ' ' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @16 '!' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x17, 0xE0, /* # ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @32 '"' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @48 '#' (8 pixels wide) */ + 0x04, 0x00, /* # */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xC0, /* ##### */ + 0x14, 0xA0, /* # # # # */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xE0, /* # ### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @64 '$' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x11, 0x80, /* # ## */ + 0x12, 0x40, /* # # # */ + 0x7F, 0xE0, /* ########## */ + 0x12, 0x40, /* # # # */ + 0x0C, 0x40, /* ## # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @80 '%' (8 pixels wide) */ + 0x04, 0xE0, /* # ### */ + 0x04, 0xA0, /* # # # */ + 0x02, 0xE0, /* # ### */ + 0x1D, 0x00, /* ### # */ + 0x15, 0x00, /* # # # */ + 0x1C, 0x80, /* ### # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @96 '&' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0x00, /* ### */ + 0x11, 0xE0, /* # #### */ + 0x13, 0x20, /* # ## # */ + 0x16, 0x20, /* # ## # */ + 0x18, 0x00, /* ## */ + 0x16, 0x00, /* # ## */ + 0x00, 0x00, /* */ + + /* @112 ''' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @128 '(' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x20, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 ')' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x30, 0x30, /* ## ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @160 '*' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x40, /* # # */ + 0x01, 0x80, /* ## */ + 0x07, 0xE0, /* ###### */ + 0x01, 0x80, /* ## */ + 0x02, 0x40, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @176 '+' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x0F, 0x80, /* ##### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @192 ',' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @208 '-' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @224 '.' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @240 '/' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @256 '0' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x18, 0x60, /* ## ## */ + 0x10, 0x20, /* # # */ + 0x11, 0x20, /* # # # */ + 0x18, 0x60, /* ## ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @272 '1' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @288 '2' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x40, /* # # */ + 0x18, 0x20, /* ## # */ + 0x14, 0x20, /* # # # */ + 0x16, 0x20, /* # ## # */ + 0x13, 0x20, /* # ## # */ + 0x11, 0xC0, /* # ### */ + 0x00, 0x00, /* */ + + /* @304 '3' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x40, /* # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x13, 0x20, /* # ## # */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @320 '4' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x06, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x04, 0x80, /* # # */ + 0x04, 0x60, /* # ## */ + 0x1F, 0xE0, /* ######## */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @336 '5' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x11, 0xE0, /* # #### */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x13, 0x20, /* # ## # */ + 0x0E, 0x00, /* ### */ + 0x00, 0x00, /* */ + + /* @352 '6' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x12, 0x40, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x0E, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @368 '7' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x10, 0x20, /* # # */ + 0x0C, 0x20, /* ## # */ + 0x03, 0x20, /* ## # */ + 0x00, 0xE0, /* ### */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @384 '8' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0xC0, /* ### ## */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @400 '9' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x11, 0xC0, /* # ### */ + 0x12, 0x20, /* # # # */ + 0x12, 0x20, /* # # # */ + 0x12, 0x20, /* # # # */ + 0x0A, 0x20, /* # # # */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @416 ':' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @432 ';' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @448 '<' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x09, 0x00, /* # # */ + 0x08, 0x80, /* # # */ + 0x00, 0x00, /* */ + + /* @464 '=' (8 pixels wide) */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @480 '>' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x80, /* # # */ + 0x09, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @496 '?' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x17, 0x20, /* # ### # */ + 0x01, 0xA0, /* ## # */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @512 '@' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x30, 0x40, /* ## # */ + 0x46, 0x20, /* # ## # */ + 0x49, 0x20, /* # # # # */ + 0x49, 0x60, /* # # # ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @528 'A' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x04, 0xE0, /* # ### */ + 0x04, 0xE0, /* # ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @544 'B' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @560 'C' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x08, 0x40, /* # # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x08, 0x40, /* # # */ + 0x00, 0x00, /* */ + + /* @576 'D' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x08, 0x40, /* # # */ + 0x07, 0x80, /* #### */ + 0x00, 0x00, /* */ + + /* @592 'E' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x00, 0x00, /* */ + + /* @608 'F' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @624 'G' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x08, 0x40, /* # # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x12, 0x20, /* # # # */ + 0x0E, 0x40, /* ### # */ + 0x00, 0x00, /* */ + + /* @640 'H' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @656 'I' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @672 'J' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @688 'K' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0x00, /* # */ + 0x02, 0x80, /* # # */ + 0x04, 0x40, /* # # */ + 0x08, 0x20, /* # # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @704 'L' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @720 'M' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0xC0, /* ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0xC0, /* ## */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @736 'N' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x40, /* # */ + 0x01, 0x80, /* ## */ + 0x06, 0x00, /* ## */ + 0x08, 0x00, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @752 'O' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x18, 0x60, /* ## ## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x18, 0x60, /* ## ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @768 'P' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x01, 0xC0, /* ### */ + 0x00, 0x00, /* */ + + /* @784 'Q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x18, 0x60, /* ## ## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x38, 0x60, /* ### ## */ + 0x2F, 0xC0, /* # ###### */ + 0x00, 0x00, /* */ + + /* @800 'R' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x06, 0x20, /* ## # */ + 0x09, 0xC0, /* # ### */ + 0x10, 0x00, /* # */ + + /* @816 'S' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0xC0, /* # ### */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x12, 0x20, /* # # # */ + 0x0E, 0x40, /* ### # */ + 0x00, 0x00, /* */ + + /* @832 'T' (8 pixels wide) */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @848 'U' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xE0, /* ####### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @864 'V' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x60, /* ## */ + 0x03, 0x80, /* ### */ + 0x1C, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x03, 0x80, /* ### */ + 0x00, 0x60, /* ## */ + 0x00, 0x00, /* */ + + /* @880 'W' (8 pixels wide) */ + 0x01, 0xE0, /* #### */ + 0x1E, 0x00, /* #### */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x1E, 0x00, /* #### */ + 0x01, 0xE0, /* #### */ + 0x00, 0x00, /* */ + + /* @896 'X' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x0C, 0xC0, /* ## ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x0C, 0xC0, /* ## ## */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @912 'Y' (8 pixels wide) */ + 0x00, 0x20, /* # */ + 0x00, 0x60, /* ## */ + 0x01, 0x80, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x01, 0x80, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @928 'Z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x1C, 0x20, /* ### # */ + 0x16, 0x20, /* # ## # */ + 0x11, 0x20, /* # # # */ + 0x10, 0xE0, /* # ### */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @944 '[' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xF0, /* ########## */ + 0x20, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @960 '\' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x20, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @976 ']' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x10, /* # # */ + 0x3F, 0xF0, /* ########## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @992 '^' (8 pixels wide) */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1008 '_' (8 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1024 '`' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1040 'a' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x80, /* ## # */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1056 'b' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1072 'c' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x19, 0x80, /* ## ## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1088 'd' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1104 'e' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x13, 0x00, /* # ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1120 'f' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x90, /* # # */ + 0x00, 0x90, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1136 'g' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x50, 0x80, /* # # # */ + 0x50, 0x80, /* # # # */ + 0x50, 0x80, /* # # # */ + 0x3F, 0x80, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1152 'h' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1168 'i' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0x90, /* ###### # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1184 'j' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x80, /* # # */ + 0x40, 0x80, /* # # */ + 0x3F, 0x90, /* ####### # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1200 'k' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x02, 0x00, /* # */ + 0x05, 0x00, /* # # */ + 0x08, 0x80, /* # # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1216 'l' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1232 'm' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1248 'n' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x01, 0x00, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1264 'o' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1280 'p' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x7F, 0x80, /* ######## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1296 'q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x7F, 0x80, /* ######## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1312 'r' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1328 's' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x13, 0x00, /* # ## */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x14, 0x80, /* # # # */ + 0x0C, 0x80, /* ## # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1344 't' (8 pixels wide) */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1360 'u' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1376 'v' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x80, /* ## */ + 0x0E, 0x00, /* ### */ + 0x10, 0x00, /* # */ + 0x0E, 0x00, /* ### */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1392 'w' (8 pixels wide) */ + 0x01, 0x80, /* ## */ + 0x06, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + + /* @1408 'x' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x80, /* # # */ + 0x19, 0x80, /* ## ## */ + 0x06, 0x00, /* ## */ + 0x19, 0x80, /* ## ## */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1424 'y' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x41, 0x80, /* # ## */ + 0x6E, 0x00, /* ## ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1440 'z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x80, /* # # */ + 0x1C, 0x80, /* ### # */ + 0x16, 0x80, /* # ## # */ + 0x13, 0x80, /* # ### */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1456 '{' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x3E, 0xF0, /* ##### #### */ + 0x20, 0x10, /* # # */ + 0x20, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1472 '|' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x7F, 0xF0, /* ########### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1488 '}' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x10, /* # # */ + 0x20, 0x10, /* # # */ + 0x3E, 0xF0, /* ##### #### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1504 '~' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ +}; + +/* Character descriptors for DejaVu Sans Mono 8pt */ +/* { [Char width in bits], [Offset into dejaVuSansMono8ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dejaVuSansMono8ptCharDescriptors[] = +{ + {8, 0}, /* */ + {8, 16}, /* ! */ + {8, 32}, /* " */ + {8, 48}, /* # */ + {8, 64}, /* $ */ + {8, 80}, /* % */ + {8, 96}, /* & */ + {8, 112}, /* ' */ + {8, 128}, /* ( */ + {8, 144}, /* ) */ + {8, 160}, /* * */ + {8, 176}, /* + */ + {8, 192}, /* , */ + {8, 208}, /* - */ + {8, 224}, /* . */ + {8, 240}, /* / */ + {8, 256}, /* 0 */ + {8, 272}, /* 1 */ + {8, 288}, /* 2 */ + {8, 304}, /* 3 */ + {8, 320}, /* 4 */ + {8, 336}, /* 5 */ + {8, 352}, /* 6 */ + {8, 368}, /* 7 */ + {8, 384}, /* 8 */ + {8, 400}, /* 9 */ + {8, 416}, /* : */ + {8, 432}, /* ; */ + {8, 448}, /* < */ + {8, 464}, /* = */ + {8, 480}, /* > */ + {8, 496}, /* ? */ + {8, 512}, /* @ */ + {8, 528}, /* A */ + {8, 544}, /* B */ + {8, 560}, /* C */ + {8, 576}, /* D */ + {8, 592}, /* E */ + {8, 608}, /* F */ + {8, 624}, /* G */ + {8, 640}, /* H */ + {8, 656}, /* I */ + {8, 672}, /* J */ + {8, 688}, /* K */ + {8, 704}, /* L */ + {8, 720}, /* M */ + {8, 736}, /* N */ + {8, 752}, /* O */ + {8, 768}, /* P */ + {8, 784}, /* Q */ + {8, 800}, /* R */ + {8, 816}, /* S */ + {8, 832}, /* T */ + {8, 848}, /* U */ + {8, 864}, /* V */ + {8, 880}, /* W */ + {8, 896}, /* X */ + {8, 912}, /* Y */ + {8, 928}, /* Z */ + {8, 944}, /* [ */ + {8, 960}, /* \ */ + {8, 976}, /* ] */ + {8, 992}, /* ^ */ + {8, 1008}, /* _ */ + {8, 1024}, /* ` */ + {8, 1040}, /* a */ + {8, 1056}, /* b */ + {8, 1072}, /* c */ + {8, 1088}, /* d */ + {8, 1104}, /* e */ + {8, 1120}, /* f */ + {8, 1136}, /* g */ + {8, 1152}, /* h */ + {8, 1168}, /* i */ + {8, 1184}, /* j */ + {8, 1200}, /* k */ + {8, 1216}, /* l */ + {8, 1232}, /* m */ + {8, 1248}, /* n */ + {8, 1264}, /* o */ + {8, 1280}, /* p */ + {8, 1296}, /* q */ + {8, 1312}, /* r */ + {8, 1328}, /* s */ + {8, 1344}, /* t */ + {8, 1360}, /* u */ + {8, 1376}, /* v */ + {8, 1392}, /* w */ + {8, 1408}, /* x */ + {8, 1424}, /* y */ + {8, 1440}, /* z */ + {8, 1456}, /* { */ + {8, 1472}, /* | */ + {8, 1488}, /* } */ + {8, 1504}, /* ~ */ +}; + +/* Font information for DejaVu Sans Mono 8pt */ +const FONT_INFO dejaVuSansMono8ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + dejaVuSansMono8ptCharDescriptors, /* Character decriptor array */ + dejaVuSansMono8ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/dejavusansmono8.h b/drivers/lcd/tft/fonts/dejavusansmono8.h new file mode 100644 index 0000000..3310409 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansmono8.h @@ -0,0 +1,10 @@ +#ifndef __DEJA_VU_SANS_MONO_8__ +#define __DEJA_VU_SANS_MONO_8__ + +#include "bitmapfonts.h" + +extern const uint8_t dejaVuSansMono8ptCharBitmaps[]; +extern const FONT_CHAR_INFO dejaVuSansMono8ptCharDescriptors[]; +extern const FONT_INFO dejaVuSansMono8ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/dejavusansmonobold8.c b/drivers/lcd/tft/fonts/dejavusansmonobold8.c new file mode 100644 index 0000000..0a057e6 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansmonobold8.c @@ -0,0 +1,1069 @@ +#include "dejavusansmonobold8.h" + +/* +** Font data for DejaVu Sans Mono Bold 8pt +*/ + +/* Character bitmaps for DejaVu Sans Mono Bold 8pt */ +const uint8_t dejaVuSansMonoBold8ptCharBitmaps[] = +{ + /* @0 ' ' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @16 '!' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1B, 0xE0, /* ## ##### */ + 0x1B, 0xE0, /* ## ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @32 '"' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @48 '#' (8 pixels wide) */ + 0x04, 0x00, /* # */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xC0, /* ##### */ + 0x1C, 0xE0, /* ### ### */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xE0, /* # ### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @64 '$' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0x80, /* # ## */ + 0x13, 0x40, /* # ## # */ + 0x7F, 0xE0, /* ########## */ + 0x13, 0x40, /* # ## # */ + 0x0E, 0x00, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @80 '%' (8 pixels wide) */ + 0x04, 0xE0, /* # ### */ + 0x04, 0xA0, /* # # # */ + 0x02, 0xE0, /* # ### */ + 0x1D, 0x00, /* ### # */ + 0x15, 0x00, /* # # # */ + 0x1C, 0x80, /* ### # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @96 '&' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0x00, /* ### */ + 0x1E, 0xE0, /* #### ### */ + 0x13, 0xE0, /* # ##### */ + 0x1E, 0x20, /* #### # */ + 0x18, 0x00, /* ## */ + 0x1E, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @112 ''' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @128 '(' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x1F, 0xE0, /* ######## */ + 0x30, 0x30, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 ')' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x30, 0x30, /* ## ## */ + 0x1F, 0xE0, /* ######## */ + 0x07, 0x80, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @160 '*' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x40, /* # # */ + 0x01, 0x80, /* ## */ + 0x07, 0xE0, /* ###### */ + 0x01, 0x80, /* ## */ + 0x02, 0x40, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @176 '+' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x0F, 0x80, /* ##### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @192 ',' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x38, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @208 '-' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @224 '.' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @240 '/' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @256 '0' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x11, 0x20, /* # # # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @272 '1' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @288 '2' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x18, 0x20, /* ## # */ + 0x14, 0x20, /* # # # */ + 0x13, 0x20, /* # ## # */ + 0x11, 0xE0, /* # #### */ + 0x10, 0xC0, /* # ## */ + 0x00, 0x00, /* */ + + /* @304 '3' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x1E, 0xE0, /* #### ### */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @320 '4' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x06, 0x00, /* ## */ + 0x05, 0x80, /* # ## */ + 0x04, 0xC0, /* # ## */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @336 '5' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x11, 0xE0, /* # #### */ + 0x11, 0xE0, /* # #### */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x1F, 0x20, /* ##### # */ + 0x0E, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @352 '6' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xE0, /* ######## */ + 0x11, 0x60, /* # # ## */ + 0x11, 0x20, /* # # # */ + 0x1F, 0x20, /* ##### # */ + 0x0E, 0x00, /* ### */ + 0x00, 0x00, /* */ + + /* @368 '7' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x10, 0x20, /* # # */ + 0x1E, 0x20, /* #### # */ + 0x0F, 0xA0, /* ##### # */ + 0x03, 0xE0, /* ##### */ + 0x00, 0x60, /* ## */ + 0x00, 0x00, /* */ + + /* @384 '8' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0xC0, /* ### ## */ + 0x1E, 0xE0, /* #### ### */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x1E, 0xE0, /* #### ### */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @400 '9' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xC0, /* ### */ + 0x13, 0xE0, /* # ##### */ + 0x12, 0x20, /* # # # */ + 0x1A, 0x20, /* ## # # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @416 ':' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x19, 0x80, /* ## ## */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @432 ';' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x39, 0x80, /* ### ## */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @448 '<' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x0F, 0x00, /* #### */ + 0x09, 0x00, /* # # */ + 0x09, 0x00, /* # # */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + + /* @464 '=' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x00, 0x00, /* */ + + /* @480 '>' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x19, 0x80, /* ## ## */ + 0x09, 0x00, /* # # */ + 0x09, 0x00, /* # # */ + 0x0F, 0x00, /* #### */ + 0x06, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @496 '?' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x40, /* # */ + 0x1B, 0x20, /* ## ## # */ + 0x1A, 0xE0, /* ## # ### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @512 '@' (8 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x27, 0x20, /* # ### # */ + 0x28, 0xA0, /* # # # # */ + 0x28, 0xA0, /* # # # # */ + 0x3F, 0xC0, /* ######## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @528 'A' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x1F, 0x80, /* ###### */ + 0x05, 0xE0, /* # #### */ + 0x05, 0xE0, /* # #### */ + 0x1F, 0x80, /* ###### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @544 'B' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x1E, 0xE0, /* #### ### */ + 0x0E, 0xC0, /* ### ## */ + 0x00, 0x00, /* */ + + /* @560 'C' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x0F, 0xC0, /* ###### */ + 0x18, 0x60, /* ## ## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x08, 0x40, /* # # */ + 0x00, 0x00, /* */ + + /* @576 'D' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @592 'E' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x11, 0x20, /* # # # */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @608 'F' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @624 'G' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x0F, 0xC0, /* ###### */ + 0x18, 0x60, /* ## ## */ + 0x12, 0x20, /* # # # */ + 0x1E, 0x20, /* #### # */ + 0x1E, 0x40, /* #### # */ + 0x00, 0x00, /* */ + + /* @640 'H' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @656 'I' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @672 'J' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @688 'K' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x03, 0x00, /* ## */ + 0x07, 0xC0, /* ##### */ + 0x1C, 0x60, /* ### ## */ + 0x18, 0x20, /* ## # */ + 0x00, 0x00, /* */ + + /* @704 'L' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @720 'M' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xC0, /* ####### */ + 0x03, 0x80, /* ### */ + 0x03, 0x80, /* ### */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @736 'N' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0xC0, /* ### */ + 0x0E, 0x00, /* ### */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x00, /* */ + + /* @752 'O' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @768 'P' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x03, 0xE0, /* ##### */ + 0x01, 0xC0, /* ### */ + 0x00, 0x00, /* */ + + /* @784 'Q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x20, /* # # */ + 0x10, 0x20, /* # # */ + 0x3F, 0xE0, /* ######### */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @800 'R' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x0D, 0xE0, /* ## #### */ + 0x19, 0xC0, /* ## ### */ + 0x10, 0x00, /* # */ + + /* @816 'S' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0xC0, /* # ### */ + 0x11, 0xE0, /* # #### */ + 0x13, 0x20, /* # ## # */ + 0x13, 0x20, /* # ## # */ + 0x1E, 0x20, /* #### # */ + 0x0E, 0x40, /* ### # */ + 0x00, 0x00, /* */ + + /* @832 'T' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x00, 0x20, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @848 'U' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xE0, /* ####### */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @864 'V' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x60, /* ## */ + 0x07, 0xE0, /* ###### */ + 0x1E, 0x00, /* #### */ + 0x1E, 0x00, /* #### */ + 0x07, 0xE0, /* ###### */ + 0x00, 0x60, /* ## */ + 0x00, 0x00, /* */ + + /* @880 'W' (8 pixels wide) */ + 0x01, 0xE0, /* #### */ + 0x1F, 0xE0, /* ######## */ + 0x1E, 0x00, /* #### */ + 0x01, 0x80, /* ## */ + 0x1E, 0x00, /* #### */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0xE0, /* #### */ + 0x00, 0x00, /* */ + + /* @896 'X' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x1C, 0xE0, /* ### ### */ + 0x07, 0x80, /* #### */ + 0x07, 0x80, /* #### */ + 0x1C, 0xE0, /* ### ### */ + 0x10, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @912 'Y' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x01, 0xE0, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x01, 0xE0, /* #### */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + + /* @928 'Z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x20, /* ## # */ + 0x1C, 0x20, /* ### # */ + 0x17, 0x20, /* # ### # */ + 0x11, 0xA0, /* # ## # */ + 0x10, 0xE0, /* # ### */ + 0x10, 0x60, /* # ## */ + 0x00, 0x00, /* */ + + /* @944 '[' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xF0, /* ########## */ + 0x3F, 0xF0, /* ########## */ + 0x20, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @960 '\' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x20, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @976 ']' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x10, /* # # */ + 0x3F, 0xF0, /* ########## */ + 0x3F, 0xF0, /* ########## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @992 '^' (8 pixels wide) */ + 0x00, 0x80, /* # */ + 0x00, 0xC0, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1008 '_' (8 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1024 '`' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x30, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1040 'a' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x00, /* ## */ + 0x1E, 0x80, /* #### # */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + + /* @1056 'b' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0x80, /* ###### */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @1072 'c' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x19, 0x80, /* ## ## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + + /* @1088 'd' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @1104 'e' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x12, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x13, 0x80, /* # ### */ + 0x13, 0x00, /* # ## */ + 0x00, 0x00, /* */ + + /* @1120 'f' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x90, /* # # */ + 0x00, 0x90, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1136 'g' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x5F, 0x80, /* # ###### */ + 0x50, 0x80, /* # # # */ + 0x50, 0x80, /* # # # */ + 0x7F, 0x80, /* ######## */ + 0x3F, 0x80, /* ####### */ + 0x00, 0x00, /* */ + + /* @1152 'h' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + + /* @1168 'i' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0xB0, /* ###### ## */ + 0x1F, 0xB0, /* ###### ## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1184 'j' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x80, /* # # */ + 0x40, 0x80, /* # # */ + 0x7F, 0xB0, /* ######## ## */ + 0x3F, 0xB0, /* ####### ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1200 'k' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x02, 0x00, /* # */ + 0x0F, 0x80, /* ##### */ + 0x18, 0x80, /* ## # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1216 'l' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1232 'm' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + + /* @1248 'n' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x00, /* ##### */ + 0x00, 0x00, /* */ + + /* @1264 'o' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0x80, /* ###### */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @1280 'p' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x7F, 0x80, /* ######## */ + 0x7F, 0x80, /* ######## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x1F, 0x80, /* ###### */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @1296 'q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x00, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x7F, 0x80, /* ######## */ + 0x7F, 0x80, /* ######## */ + 0x00, 0x00, /* */ + + /* @1312 'r' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @1328 's' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0B, 0x00, /* # ## */ + 0x13, 0x80, /* # ### */ + 0x16, 0x80, /* # ## # */ + 0x16, 0x80, /* # ## # */ + 0x1C, 0x80, /* ### # */ + 0x0D, 0x00, /* ## # */ + 0x00, 0x00, /* */ + + /* @1344 't' (8 pixels wide) */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xE0, /* ######## */ + 0x10, 0x80, /* # # */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1360 'u' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0x80, /* ###### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + + /* @1376 'v' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x80, /* ## */ + 0x0F, 0x80, /* ##### */ + 0x1C, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x0F, 0x80, /* ##### */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + + /* @1392 'w' (8 pixels wide) */ + 0x01, 0x80, /* ## */ + 0x1F, 0x80, /* ###### */ + 0x1C, 0x00, /* ### */ + 0x02, 0x00, /* # */ + 0x1C, 0x00, /* ### */ + 0x1F, 0x80, /* ###### */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + + /* @1408 'x' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x80, /* # # */ + 0x19, 0x80, /* ## ## */ + 0x0F, 0x00, /* #### */ + 0x0F, 0x00, /* #### */ + 0x19, 0x80, /* ## ## */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + + /* @1424 'y' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x80, /* # # */ + 0x47, 0x80, /* # #### */ + 0x7C, 0x00, /* ##### */ + 0x1E, 0x00, /* #### */ + 0x07, 0x80, /* #### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @1440 'z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x80, /* ## # */ + 0x1C, 0x80, /* ### # */ + 0x14, 0x80, /* # # # */ + 0x12, 0x80, /* # # # */ + 0x13, 0x80, /* # ### */ + 0x11, 0x80, /* # ## */ + 0x00, 0x00, /* */ + + /* @1456 '{' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x3D, 0xF0, /* #### ##### */ + 0x3D, 0xF0, /* #### ##### */ + 0x20, 0x10, /* # # */ + 0x20, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @1472 '|' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x7F, 0xF0, /* ########### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1488 '}' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x10, /* # # */ + 0x20, 0x10, /* # # */ + 0x3D, 0xF0, /* #### ##### */ + 0x3D, 0xF0, /* #### ##### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1504 '~' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ +}; + +/* Character descriptors for DejaVu Sans Mono 8pt */ +/* { [Char width in bits], [Offset into dejaVuSansMonoBold8ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO dejaVuSansMonoBold8ptCharDescriptors[] = +{ + {8, 0}, /* */ + {8, 16}, /* ! */ + {8, 32}, /* " */ + {8, 48}, /* # */ + {8, 64}, /* $ */ + {8, 80}, /* % */ + {8, 96}, /* & */ + {8, 112}, /* ' */ + {8, 128}, /* ( */ + {8, 144}, /* ) */ + {8, 160}, /* * */ + {8, 176}, /* + */ + {8, 192}, /* , */ + {8, 208}, /* - */ + {8, 224}, /* . */ + {8, 240}, /* / */ + {8, 256}, /* 0 */ + {8, 272}, /* 1 */ + {8, 288}, /* 2 */ + {8, 304}, /* 3 */ + {8, 320}, /* 4 */ + {8, 336}, /* 5 */ + {8, 352}, /* 6 */ + {8, 368}, /* 7 */ + {8, 384}, /* 8 */ + {8, 400}, /* 9 */ + {8, 416}, /* : */ + {8, 432}, /* ; */ + {8, 448}, /* < */ + {8, 464}, /* = */ + {8, 480}, /* > */ + {8, 496}, /* ? */ + {8, 512}, /* @ */ + {8, 528}, /* A */ + {8, 544}, /* B */ + {8, 560}, /* C */ + {8, 576}, /* D */ + {8, 592}, /* E */ + {8, 608}, /* F */ + {8, 624}, /* G */ + {8, 640}, /* H */ + {8, 656}, /* I */ + {8, 672}, /* J */ + {8, 688}, /* K */ + {8, 704}, /* L */ + {8, 720}, /* M */ + {8, 736}, /* N */ + {8, 752}, /* O */ + {8, 768}, /* P */ + {8, 784}, /* Q */ + {8, 800}, /* R */ + {8, 816}, /* S */ + {8, 832}, /* T */ + {8, 848}, /* U */ + {8, 864}, /* V */ + {8, 880}, /* W */ + {8, 896}, /* X */ + {8, 912}, /* Y */ + {8, 928}, /* Z */ + {8, 944}, /* [ */ + {8, 960}, /* \ */ + {8, 976}, /* ] */ + {8, 992}, /* ^ */ + {8, 1008}, /* _ */ + {8, 1024}, /* ` */ + {8, 1040}, /* a */ + {8, 1056}, /* b */ + {8, 1072}, /* c */ + {8, 1088}, /* d */ + {8, 1104}, /* e */ + {8, 1120}, /* f */ + {8, 1136}, /* g */ + {8, 1152}, /* h */ + {8, 1168}, /* i */ + {8, 1184}, /* j */ + {8, 1200}, /* k */ + {8, 1216}, /* l */ + {8, 1232}, /* m */ + {8, 1248}, /* n */ + {8, 1264}, /* o */ + {8, 1280}, /* p */ + {8, 1296}, /* q */ + {8, 1312}, /* r */ + {8, 1328}, /* s */ + {8, 1344}, /* t */ + {8, 1360}, /* u */ + {8, 1376}, /* v */ + {8, 1392}, /* w */ + {8, 1408}, /* x */ + {8, 1424}, /* y */ + {8, 1440}, /* z */ + {8, 1456}, /* { */ + {8, 1472}, /* | */ + {8, 1488}, /* } */ + {8, 1504}, /* ~ */ +}; + +/* Font information for DejaVu Sans Mono 8pt */ +const FONT_INFO dejaVuSansMonoBold8ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + dejaVuSansMonoBold8ptCharDescriptors, /* Character decriptor array */ + dejaVuSansMonoBold8ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/dejavusansmonobold8.h b/drivers/lcd/tft/fonts/dejavusansmonobold8.h new file mode 100644 index 0000000..4a38f88 --- /dev/null +++ b/drivers/lcd/tft/fonts/dejavusansmonobold8.h @@ -0,0 +1,10 @@ +#ifndef __DEJA_VU_SANS_MONO_BOLD_8__ +#define __DEJA_VU_SANS_MONO_BOLD_8__ + +#include "bitmapfonts.h" + +extern const uint8_t dejaVuSansMonoBold8ptCharBitmaps[]; +extern const FONT_CHAR_INFO dejaVuSansMonoBold8ptCharDescriptors[]; +extern const FONT_INFO dejaVuSansMonoBold8ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/veramono11.c b/drivers/lcd/tft/fonts/veramono11.c new file mode 100644 index 0000000..082b7c7 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramono11.c @@ -0,0 +1,1164 @@ +#include "veramono11.h" + +/* +** Font data for Bitstream Vera Sans Mono 11pt +*/ + +/* Character bitmaps for Bitstream Vera Sans Mono 11pt */ +const uint8_t bitstreamVeraSansMono11ptCharBitmaps[] = +{ + /* @0 ' ' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @18 '!' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0C, 0xFE, /* ## ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @36 '"' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @54 '#' (9 pixels wide) */ + 0x01, 0x00, /* # */ + 0x09, 0x10, /* # # # */ + 0x07, 0xD0, /* ##### # */ + 0x01, 0x7C, /* # ##### */ + 0x0D, 0x16, /* ## # # ## */ + 0x07, 0xD0, /* ##### # */ + 0x01, 0x7C, /* # ##### */ + 0x01, 0x16, /* # # ## */ + 0x00, 0x10, /* # */ + + /* @72 '$' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x38, /* # ### */ + 0x08, 0x4C, /* # # ## */ + 0x08, 0x44, /* # # # */ + 0x3F, 0xFF, /* ############## */ + 0x08, 0x84, /* # # # */ + 0x08, 0x84, /* # # # */ + 0x07, 0x08, /* ### # */ + 0x00, 0x00, /* */ + + /* @90 '%' (9 pixels wide) */ + 0x00, 0x1C, /* ### */ + 0x00, 0xA2, /* # # # */ + 0x00, 0xA2, /* # # # */ + 0x00, 0x62, /* ## # */ + 0x07, 0x5C, /* ### # ### */ + 0x08, 0xC0, /* # ## */ + 0x08, 0xA0, /* # # # */ + 0x08, 0xA0, /* # # # */ + 0x07, 0x00, /* ### */ + + /* @108 '&' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x04, 0x7C, /* # ##### */ + 0x08, 0x32, /* # ## # */ + 0x08, 0x62, /* # ## # */ + 0x09, 0x82, /* # ## # */ + 0x07, 0x02, /* ### # */ + 0x09, 0xC0, /* # ### */ + 0x00, 0x00, /* */ + + /* @126 ''' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 '(' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x07, 0xF0, /* ####### */ + 0x18, 0x0C, /* ## ## */ + 0x20, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @162 ')' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x02, /* # # */ + 0x18, 0x0C, /* ## ## */ + 0x07, 0xF0, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @180 '*' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x24, /* # # */ + 0x00, 0x28, /* # # */ + 0x00, 0x18, /* ## */ + 0x00, 0x7E, /* ###### */ + 0x00, 0x18, /* ## */ + 0x00, 0x28, /* # # */ + 0x00, 0x24, /* # # */ + 0x00, 0x00, /* */ + + /* @198 '+' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x07, 0xF0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @216 ',' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x1C, 0x00, /* ### */ + 0x0C, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @234 '-' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @252 '.' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0C, 0x00, /* ## */ + 0x0C, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @270 '/' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x00, /* # */ + 0x0C, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0x30, /* ## */ + 0x00, 0x0C, /* ## */ + 0x00, 0x02, /* # */ + 0x00, 0x00, /* */ + + /* @288 '0' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x04, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x62, /* # ## # */ + 0x08, 0x62, /* # ## # */ + 0x04, 0x04, /* # # */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @306 '1' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x08, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @324 '2' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x0C, /* # ## */ + 0x0C, 0x06, /* ## ## */ + 0x0A, 0x02, /* # # # */ + 0x09, 0x02, /* # # # */ + 0x08, 0x82, /* # # # */ + 0x08, 0x44, /* # # # */ + 0x08, 0x3C, /* # #### */ + 0x00, 0x00, /* */ + + /* @342 '3' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x0C, 0xA4, /* ## # # # */ + 0x07, 0xBC, /* #### #### */ + 0x00, 0x00, /* */ + + /* @360 '4' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x80, /* ## */ + 0x01, 0x60, /* # ## */ + 0x01, 0x30, /* # ## */ + 0x01, 0x0C, /* # ## */ + 0x01, 0x06, /* # ## */ + 0x0F, 0xFE, /* ########### */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @378 '5' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x7E, /* # ###### */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x04, 0x42, /* # # # */ + 0x03, 0x80, /* ### */ + 0x00, 0x00, /* */ + + /* @396 '6' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF0, /* ###### */ + 0x04, 0x4C, /* # # ## */ + 0x08, 0x26, /* # # ## */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x0C, 0x62, /* ## ## # */ + 0x07, 0xC4, /* ##### # */ + 0x00, 0x00, /* */ + + /* @414 '7' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x08, 0x02, /* # # */ + 0x06, 0x02, /* ## # */ + 0x01, 0x82, /* ## # */ + 0x00, 0x62, /* ## # */ + 0x00, 0x1E, /* #### */ + 0x00, 0x06, /* ## */ + 0x00, 0x00, /* */ + + /* @432 '8' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xBC, /* #### #### */ + 0x0C, 0xA6, /* ## # # ## */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x0C, 0xA6, /* ## # # ## */ + 0x07, 0xBC, /* #### #### */ + 0x00, 0x00, /* */ + + /* @450 '9' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x7C, /* # ##### */ + 0x08, 0xC6, /* # ## ## */ + 0x08, 0x82, /* # # # */ + 0x08, 0x82, /* # # # */ + 0x0C, 0x82, /* ## # # */ + 0x06, 0x44, /* ## # # */ + 0x01, 0xF8, /* ###### */ + 0x00, 0x00, /* */ + + /* @468 ':' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0C, 0x30, /* ## ## */ + 0x0C, 0x30, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @486 ';' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x1C, 0x30, /* ### ## */ + 0x0C, 0x30, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @504 '<' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x01, 0xC0, /* ### */ + 0x01, 0x40, /* # # */ + 0x01, 0x40, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x04, 0x10, /* # # */ + + /* @522 '=' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + 0x01, 0x20, /* # # */ + + /* @540 '>' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x10, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x01, 0x40, /* # # */ + 0x01, 0x40, /* # # */ + 0x01, 0xC0, /* ### */ + 0x00, 0x80, /* # */ + + /* @558 '?' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x04, /* # */ + 0x00, 0x02, /* # */ + 0x0D, 0xC2, /* ## ### # */ + 0x00, 0x42, /* # # */ + 0x00, 0x22, /* # # */ + 0x00, 0x1C, /* ### */ + 0x00, 0x00, /* */ + + /* @576 '@' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xE0, /* ###### */ + 0x18, 0x18, /* ## ## */ + 0x10, 0x0C, /* # ## */ + 0x23, 0xC4, /* # #### # */ + 0x24, 0x24, /* # # # # */ + 0x24, 0x2C, /* # # # ## */ + 0x07, 0xF8, /* ######## */ + 0x00, 0x00, /* */ + + /* @594 'A' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x00, /* ## */ + 0x03, 0xC0, /* #### */ + 0x01, 0x3C, /* # #### */ + 0x01, 0x02, /* # # */ + 0x01, 0x3C, /* # #### */ + 0x03, 0xC0, /* #### */ + 0x0C, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @612 'B' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x0C, 0xE6, /* ## ### ## */ + 0x07, 0xBC, /* #### #### */ + 0x00, 0x00, /* */ + + /* @630 'C' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xF0, /* ##### */ + 0x06, 0x0C, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x04, 0x04, /* # # */ + 0x00, 0x00, /* */ + + /* @648 'D' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0C, 0x06, /* ## ## */ + 0x06, 0x0C, /* ## ## */ + 0x01, 0xF0, /* ##### */ + 0x00, 0x00, /* */ + + /* @666 'E' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x00, 0x00, /* */ + + /* @684 'F' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x00, /* */ + + /* @702 'G' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xF0, /* ##### */ + 0x06, 0x0C, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x07, 0xC4, /* ##### # */ + 0x00, 0x00, /* */ + + /* @720 'H' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @738 'I' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @756 'J' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0C, 0x02, /* ## # */ + 0x07, 0xFE, /* ########## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @774 'K' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0xD0, /* ## # */ + 0x01, 0x08, /* # # */ + 0x06, 0x04, /* ## # */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + + /* @792 'L' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @810 'M' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x0E, /* ### */ + 0x00, 0x70, /* ### */ + 0x00, 0x80, /* # */ + 0x00, 0x70, /* ### */ + 0x00, 0x0E, /* ### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @828 'N' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x06, /* ## */ + 0x00, 0x18, /* ## */ + 0x00, 0xE0, /* ### */ + 0x03, 0x00, /* ## */ + 0x0C, 0x00, /* ## */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @846 'O' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x04, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x04, 0x04, /* # # */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @864 'P' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x82, /* # # */ + 0x00, 0x82, /* # # */ + 0x00, 0x82, /* # # */ + 0x00, 0x82, /* # # */ + 0x00, 0xC6, /* ## ## */ + 0x00, 0x7C, /* ##### */ + 0x00, 0x00, /* */ + + /* @882 'Q' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x04, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x18, 0x02, /* ## # */ + 0x3C, 0x04, /* #### # */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @900 'R' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0xA6, /* # # ## */ + 0x07, 0x3C, /* ### #### */ + 0x08, 0x00, /* # */ + + /* @918 'S' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x3C, /* # #### */ + 0x0C, 0x24, /* ## # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x0C, 0x86, /* ## # ## */ + 0x07, 0x84, /* #### # */ + 0x00, 0x00, /* */ + + /* @936 'T' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x00, /* */ + + /* @954 'U' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xFE, /* ########## */ + 0x0C, 0x00, /* ## */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x0C, 0x00, /* ## */ + 0x07, 0xFE, /* ########## */ + 0x00, 0x00, /* */ + + /* @972 'V' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x06, /* ## */ + 0x00, 0x78, /* #### */ + 0x07, 0x80, /* #### */ + 0x08, 0x00, /* # */ + 0x07, 0x80, /* #### */ + 0x00, 0x78, /* #### */ + 0x00, 0x06, /* ## */ + 0x00, 0x00, /* */ + + /* @990 'W' (9 pixels wide) */ + 0x00, 0x0E, /* ### */ + 0x03, 0xF0, /* ###### */ + 0x0C, 0x00, /* ## */ + 0x03, 0xE0, /* ##### */ + 0x00, 0x10, /* # */ + 0x03, 0xE0, /* ##### */ + 0x0C, 0x00, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0x0E, /* ### */ + + /* @1008 'X' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x02, /* # # */ + 0x06, 0x0C, /* ## ## */ + 0x01, 0xB0, /* ## ## */ + 0x00, 0x40, /* # */ + 0x01, 0xB0, /* ## ## */ + 0x06, 0x0C, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + + /* @1026 'Y' (9 pixels wide) */ + 0x00, 0x02, /* # */ + 0x00, 0x06, /* ## */ + 0x00, 0x18, /* ## */ + 0x00, 0x30, /* ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x20, /* # */ + 0x00, 0x18, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x02, /* # */ + + /* @1044 'Z' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x02, /* ## # */ + 0x0A, 0x02, /* # # # */ + 0x09, 0x82, /* # ## # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x32, /* # ## # */ + 0x08, 0x0A, /* # # # */ + 0x08, 0x06, /* # ## */ + 0x00, 0x00, /* */ + + /* @1062 '[' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xFE, /* ############# */ + 0x20, 0x02, /* # # */ + 0x20, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1080 '\' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x00, 0x0C, /* ## */ + 0x00, 0x30, /* ## */ + 0x00, 0xC0, /* ## */ + 0x03, 0x00, /* ## */ + 0x0C, 0x00, /* ## */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1098 ']' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x02, /* # # */ + 0x20, 0x02, /* # # */ + 0x3F, 0xFE, /* ############# */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1116 '^' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x18, /* ## */ + 0x00, 0x0C, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x0C, /* ## */ + 0x00, 0x18, /* ## */ + 0x00, 0x10, /* # */ + + /* @1134 '_' (9 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1152 '`' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x01, /* # */ + 0x00, 0x03, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x04, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1170 'a' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x00, /* ### */ + 0x09, 0xA0, /* # ## # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x04, 0x90, /* # # # */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1188 'b' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x03, 0xC0, /* #### */ + 0x00, 0x00, /* */ + + /* @1206 'c' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1224 'd' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @1242 'e' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x05, 0x20, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x09, 0x20, /* # # # */ + 0x05, 0xC0, /* # ### */ + 0x00, 0x00, /* */ + + /* @1260 'f' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xFC, /* ########## */ + 0x00, 0x12, /* # # */ + 0x00, 0x12, /* # # */ + 0x00, 0x12, /* # # */ + 0x00, 0x00, /* */ + + /* @1278 'g' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x24, 0x20, /* # # # */ + 0x48, 0x10, /* # # # */ + 0x48, 0x10, /* # # # */ + 0x48, 0x10, /* # # # */ + 0x64, 0x20, /* ## # # */ + 0x3F, 0xF0, /* ########## */ + 0x00, 0x00, /* */ + + /* @1296 'h' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x30, /* ## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1314 'i' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x0F, 0xF6, /* ######## ## */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1332 'j' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + 0x3F, 0xF6, /* ########## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1350 'k' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x80, /* # */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + 0x02, 0x20, /* # # */ + 0x04, 0x10, /* # # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1368 'l' (9 pixels wide) */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x07, 0xFE, /* ########## */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1386 'm' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1404 'n' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x30, /* ## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1422 'o' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x03, 0xC0, /* #### */ + 0x00, 0x00, /* */ + + /* @1440 'p' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x7F, 0xF0, /* ########### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x03, 0xC0, /* #### */ + 0x00, 0x00, /* */ + + /* @1458 'q' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x04, 0x20, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x7F, 0xF0, /* ########### */ + 0x00, 0x00, /* */ + + /* @1476 'r' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + + /* @1494 's' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0xE0, /* # ### */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x07, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @1512 't' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x07, 0xFC, /* ######### */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1530 'u' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xF0, /* ####### */ + 0x0C, 0x00, /* ## */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + + /* @1548 'v' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0xE0, /* ### */ + 0x07, 0x00, /* ### */ + 0x08, 0x00, /* # */ + 0x07, 0x00, /* ### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @1566 'w' (9 pixels wide) */ + 0x00, 0x30, /* ## */ + 0x03, 0xC0, /* #### */ + 0x0C, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0xC0, /* ## */ + 0x03, 0x00, /* ## */ + 0x0C, 0x00, /* ## */ + 0x03, 0xC0, /* #### */ + 0x00, 0x30, /* ## */ + + /* @1584 'x' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x02, 0x40, /* # # */ + 0x01, 0x80, /* ## */ + 0x02, 0x40, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @1602 'y' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x40, 0xE0, /* # ### */ + 0x43, 0x00, /* # ## */ + 0x3C, 0x00, /* #### */ + 0x07, 0x00, /* ### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @1620 'z' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x10, /* ## # */ + 0x0A, 0x10, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x09, 0x10, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x50, /* # # # */ + 0x08, 0x30, /* # ## */ + 0x00, 0x00, /* */ + + /* @1638 '{' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x3F, 0x7C, /* ###### ##### */ + 0x40, 0x02, /* # # */ + 0x40, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1656 '|' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0xFF, 0xFE, /* ############### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1674 '}' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x40, 0x02, /* # # */ + 0x40, 0x02, /* # # */ + 0x3F, 0x7C, /* ###### ##### */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1692 '~' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ +}; + +/* Character descriptors for Bitstream Vera Sans Mono 11pt */ +/* { [Char width in bits], [Offset into bitstreamVeraSansMono11ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO bitstreamVeraSansMono11ptCharDescriptors[] = +{ + {9, 0}, /* */ + {9, 18}, /* ! */ + {9, 36}, /* " */ + {9, 54}, /* # */ + {9, 72}, /* $ */ + {9, 90}, /* % */ + {9, 108}, /* & */ + {9, 126}, /* ' */ + {9, 144}, /* ( */ + {9, 162}, /* ) */ + {9, 180}, /* * */ + {9, 198}, /* + */ + {9, 216}, /* , */ + {9, 234}, /* - */ + {9, 252}, /* . */ + {9, 270}, /* / */ + {9, 288}, /* 0 */ + {9, 306}, /* 1 */ + {9, 324}, /* 2 */ + {9, 342}, /* 3 */ + {9, 360}, /* 4 */ + {9, 378}, /* 5 */ + {9, 396}, /* 6 */ + {9, 414}, /* 7 */ + {9, 432}, /* 8 */ + {9, 450}, /* 9 */ + {9, 468}, /* : */ + {9, 486}, /* ; */ + {9, 504}, /* < */ + {9, 522}, /* = */ + {9, 540}, /* > */ + {9, 558}, /* ? */ + {9, 576}, /* @ */ + {9, 594}, /* A */ + {9, 612}, /* B */ + {9, 630}, /* C */ + {9, 648}, /* D */ + {9, 666}, /* E */ + {9, 684}, /* F */ + {9, 702}, /* G */ + {9, 720}, /* H */ + {9, 738}, /* I */ + {9, 756}, /* J */ + {9, 774}, /* K */ + {9, 792}, /* L */ + {9, 810}, /* M */ + {9, 828}, /* N */ + {9, 846}, /* O */ + {9, 864}, /* P */ + {9, 882}, /* Q */ + {9, 900}, /* R */ + {9, 918}, /* S */ + {9, 936}, /* T */ + {9, 954}, /* U */ + {9, 972}, /* V */ + {9, 990}, /* W */ + {9, 1008}, /* X */ + {9, 1026}, /* Y */ + {9, 1044}, /* Z */ + {9, 1062}, /* [ */ + {9, 1080}, /* \ */ + {9, 1098}, /* ] */ + {9, 1116}, /* ^ */ + {9, 1134}, /* _ */ + {9, 1152}, /* ` */ + {9, 1170}, /* a */ + {9, 1188}, /* b */ + {9, 1206}, /* c */ + {9, 1224}, /* d */ + {9, 1242}, /* e */ + {9, 1260}, /* f */ + {9, 1278}, /* g */ + {9, 1296}, /* h */ + {9, 1314}, /* i */ + {9, 1332}, /* j */ + {9, 1350}, /* k */ + {9, 1368}, /* l */ + {9, 1386}, /* m */ + {9, 1404}, /* n */ + {9, 1422}, /* o */ + {9, 1440}, /* p */ + {9, 1458}, /* q */ + {9, 1476}, /* r */ + {9, 1494}, /* s */ + {9, 1512}, /* t */ + {9, 1530}, /* u */ + {9, 1548}, /* v */ + {9, 1566}, /* w */ + {9, 1584}, /* x */ + {9, 1602}, /* y */ + {9, 1620}, /* z */ + {9, 1638}, /* { */ + {9, 1656}, /* | */ + {9, 1674}, /* } */ + {9, 1692}, /* ~ */ +}; + +/* Font information for Bitstream Vera Sans Mono 11pt */ +const FONT_INFO bitstreamVeraSansMono11ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + bitstreamVeraSansMono11ptCharDescriptors, /* Character decriptor array */ + bitstreamVeraSansMono11ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/veramono11.h b/drivers/lcd/tft/fonts/veramono11.h new file mode 100644 index 0000000..a887041 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramono11.h @@ -0,0 +1,11 @@ +#ifndef __VERA_MONO_11__ +#define __VERA_MONO_11__ + +#include "bitmapfonts.h" + +/* Font data for Bitstream Vera Sans Mono 11pt */ +extern const uint8_t bitstreamVeraSansMono11ptCharBitmaps[]; +extern const FONT_CHAR_INFO bitstreamVeraSansMono11ptCharDescriptors[]; +extern const FONT_INFO bitstreamVeraSansMono11ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/veramono9.c b/drivers/lcd/tft/fonts/veramono9.c new file mode 100644 index 0000000..569f39a --- /dev/null +++ b/drivers/lcd/tft/fonts/veramono9.c @@ -0,0 +1,1069 @@ +#include "veramono9.h" + +/* +** Font data for Bitstream Vera Sans Mono 9pt +*/ + +/* Character bitmaps for Bitstream Vera Sans Mono 9pt */ +const uint8_t bitstreamVeraSansMono9ptCharBitmaps[] = +{ + /* @0 ' ' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @16 '!' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1B, 0xF0, /* ## ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @32 '"' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @48 '#' (8 pixels wide) */ + 0x04, 0x00, /* # */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xC0, /* ##### */ + 0x14, 0xA0, /* # # # # */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xE0, /* # ### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @64 '$' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0xC0, /* # ### */ + 0x11, 0x20, /* # # # */ + 0x7F, 0xF0, /* ########### */ + 0x12, 0x20, /* # # # */ + 0x0E, 0x40, /* ### # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @80 '%' (8 pixels wide) */ + 0x00, 0x60, /* ## */ + 0x02, 0x90, /* # # # */ + 0x02, 0x90, /* # # # */ + 0x0D, 0x60, /* ## # ## */ + 0x13, 0x00, /* # ## */ + 0x12, 0x80, /* # # # */ + 0x0C, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @96 '&' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0x00, /* ### */ + 0x19, 0xE0, /* ## #### */ + 0x11, 0x90, /* # ## # */ + 0x16, 0x10, /* # ## # */ + 0x0C, 0x10, /* ## # */ + 0x16, 0x00, /* # ## */ + 0x00, 0x00, /* */ + + /* @112 ''' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @128 '(' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x38, 0x38, /* ### ### */ + 0x20, 0x08, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 ')' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x08, /* # # */ + 0x38, 0x38, /* ### ### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @160 '*' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x20, /* # # */ + 0x00, 0xC0, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @176 '+' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @192 ',' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @208 '-' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @224 '.' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @240 '/' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @256 '0' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x18, 0x30, /* ## ## */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @272 '1' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @288 '2' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x20, /* # # */ + 0x18, 0x10, /* ## # */ + 0x14, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x10, 0xE0, /* # ### */ + 0x00, 0x00, /* */ + + /* @304 '3' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @320 '4' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x06, 0x00, /* ## */ + 0x05, 0x80, /* # ## */ + 0x04, 0xC0, /* # ## */ + 0x04, 0x30, /* # ## */ + 0x1F, 0xF0, /* ######### */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @336 '5' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0xF0, /* # #### */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x90, /* ## ## # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @352 '6' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x19, 0x20, /* ## # # */ + 0x10, 0x90, /* # # # */ + 0x10, 0x90, /* # # # */ + 0x19, 0x90, /* ## ## # */ + 0x0F, 0x20, /* #### # */ + 0x00, 0x00, /* */ + + /* @368 '7' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x10, 0x10, /* # # */ + 0x0C, 0x10, /* ## # */ + 0x03, 0x10, /* ## # */ + 0x00, 0xF0, /* #### */ + 0x00, 0x30, /* ## */ + 0x00, 0x00, /* */ + + /* @384 '8' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0xE0, /* ### ### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @400 '9' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0xE0, /* # #### */ + 0x13, 0x30, /* # ## ## */ + 0x12, 0x10, /* # # # */ + 0x12, 0x10, /* # # # */ + 0x09, 0x30, /* # # ## */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @416 ':' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @432 ';' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @448 '<' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x08, 0x40, /* # # */ + 0x00, 0x00, /* */ + + /* @464 '=' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x00, 0x00, /* */ + + /* @480 '>' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x40, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @496 '?' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x1B, 0x10, /* ## ## # */ + 0x01, 0x90, /* ## # */ + 0x00, 0x90, /* # # */ + 0x00, 0x60, /* ## */ + 0x00, 0x00, /* */ + + /* @512 '@' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0x80, /* ###### */ + 0x30, 0x40, /* ## # */ + 0x46, 0x20, /* # ## # */ + 0x49, 0x20, /* # # # # */ + 0x49, 0x60, /* # # # ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @528 'A' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x07, 0x80, /* #### */ + 0x04, 0x70, /* # ### */ + 0x04, 0x70, /* # ### */ + 0x07, 0x80, /* #### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @544 'B' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @560 'C' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @576 'D' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @592 'E' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x00, 0x00, /* */ + + /* @608 'F' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @624 'G' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x0F, 0x20, /* #### # */ + 0x00, 0x00, /* */ + + /* @640 'H' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @656 'I' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @672 'J' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @688 'K' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x80, /* ## */ + 0x06, 0x40, /* ## # */ + 0x0C, 0x20, /* ## # */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @704 'L' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @720 'M' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x60, /* ## */ + 0x03, 0x80, /* ### */ + 0x03, 0x80, /* ### */ + 0x00, 0x60, /* ## */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @736 'N' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x30, /* ## */ + 0x01, 0xC0, /* ### */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @752 'O' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @768 'P' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + + /* @784 'Q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x78, 0x30, /* #### ## */ + 0x0F, 0xC0, /* ###### */ + 0x00, 0x00, /* */ + + /* @800 'R' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x03, 0x10, /* ## # */ + 0x0C, 0xE0, /* ## ### */ + 0x10, 0x00, /* # */ + + /* @816 'S' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0xE0, /* # ### */ + 0x11, 0x90, /* # ## # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x0E, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @832 'T' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @848 'U' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + + /* @864 'V' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x30, /* ## */ + 0x03, 0xC0, /* #### */ + 0x1C, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x03, 0xC0, /* #### */ + 0x00, 0x30, /* ## */ + 0x00, 0x00, /* */ + + /* @880 'W' (8 pixels wide) */ + 0x03, 0xF0, /* ###### */ + 0x1C, 0x00, /* ### */ + 0x07, 0x80, /* #### */ + 0x00, 0x60, /* ## */ + 0x07, 0x80, /* #### */ + 0x1C, 0x00, /* ### */ + 0x03, 0xF0, /* ###### */ + 0x00, 0x00, /* */ + + /* @896 'X' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x0C, 0x60, /* ## ## */ + 0x03, 0x80, /* ### */ + 0x03, 0x80, /* ### */ + 0x0C, 0x60, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @912 'Y' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @928 'Z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x10, /* ## # */ + 0x1C, 0x10, /* ### # */ + 0x13, 0x10, /* # ## # */ + 0x11, 0x90, /* # ## # */ + 0x10, 0x70, /* # ### */ + 0x10, 0x30, /* # ## */ + 0x00, 0x00, /* */ + + /* @944 '[' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xF8, /* ########### */ + 0x20, 0x08, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @960 '\' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x60, /* ## */ + 0x01, 0x80, /* ## */ + 0x06, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x20, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @976 ']' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x08, /* # # */ + 0x3F, 0xF8, /* ########### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @992 '^' (8 pixels wide) */ + 0x00, 0x40, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x20, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1008 '_' (8 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1024 '`' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x08, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1040 'a' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x80, /* ## # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1056 'b' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1072 'c' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x80, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1088 'd' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1104 'e' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x12, 0xC0, /* # # ## */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x0B, 0x80, /* # ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1120 'f' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x48, /* # # */ + 0x00, 0x48, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1136 'g' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x58, 0x40, /* # ## # */ + 0x90, 0x40, /* # # # */ + 0x90, 0x40, /* # # # */ + 0x7F, 0xC0, /* ######### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1152 'h' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1168 'i' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC8, /* ####### # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1184 'j' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x80, 0x40, /* # # */ + 0x80, 0x40, /* # # */ + 0x7F, 0xC8, /* ######### # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1200 'k' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x02, 0x00, /* # */ + 0x05, 0x00, /* # # */ + 0x08, 0x80, /* # # */ + 0x10, 0x40, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1216 'l' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x08, /* # */ + 0x00, 0x08, /* # */ + 0x0F, 0xF8, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1232 'm' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1248 'n' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x80, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1264 'o' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1280 'p' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0xFF, 0xC0, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1296 'q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0xFF, 0xC0, /* ########## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1312 'r' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @1328 's' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0x80, /* # ## */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x0C, 0x80, /* ## # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1344 't' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1360 'u' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1376 'v' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1392 'w' (8 pixels wide) */ + 0x00, 0xC0, /* ## */ + 0x07, 0x00, /* ### */ + 0x1C, 0x00, /* ### */ + 0x03, 0x00, /* ## */ + 0x1C, 0x00, /* ### */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x00, /* */ + + /* @1408 'x' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x40, /* # # */ + 0x0D, 0x80, /* ## ## */ + 0x02, 0x00, /* # */ + 0x0D, 0x80, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1424 'y' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x80, 0xC0, /* # ## */ + 0xCF, 0x00, /* ## #### */ + 0x38, 0x00, /* ### */ + 0x07, 0x00, /* ### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1440 'z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x40, /* ## # */ + 0x14, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x11, 0x40, /* # # # */ + 0x10, 0xC0, /* # ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1456 '{' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x3E, 0xF8, /* ##### ##### */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1472 '|' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x7F, 0xF8, /* ############ */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1488 '}' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x3E, 0xF8, /* ##### ##### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1504 '~' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ +}; + +/* Character descriptors for Bitstream Vera Sans Mono 9pt */ +/* { [Char width in bits], [Offset into bitstreamVeraSansMono9ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO bitstreamVeraSansMono9ptCharDescriptors[] = +{ + {8, 0}, /* */ + {8, 16}, /* ! */ + {8, 32}, /* " */ + {8, 48}, /* # */ + {8, 64}, /* $ */ + {8, 80}, /* % */ + {8, 96}, /* & */ + {8, 112}, /* ' */ + {8, 128}, /* ( */ + {8, 144}, /* ) */ + {8, 160}, /* * */ + {8, 176}, /* + */ + {8, 192}, /* , */ + {8, 208}, /* - */ + {8, 224}, /* . */ + {8, 240}, /* / */ + {8, 256}, /* 0 */ + {8, 272}, /* 1 */ + {8, 288}, /* 2 */ + {8, 304}, /* 3 */ + {8, 320}, /* 4 */ + {8, 336}, /* 5 */ + {8, 352}, /* 6 */ + {8, 368}, /* 7 */ + {8, 384}, /* 8 */ + {8, 400}, /* 9 */ + {8, 416}, /* : */ + {8, 432}, /* ; */ + {8, 448}, /* < */ + {8, 464}, /* = */ + {8, 480}, /* > */ + {8, 496}, /* ? */ + {8, 512}, /* @ */ + {8, 528}, /* A */ + {8, 544}, /* B */ + {8, 560}, /* C */ + {8, 576}, /* D */ + {8, 592}, /* E */ + {8, 608}, /* F */ + {8, 624}, /* G */ + {8, 640}, /* H */ + {8, 656}, /* I */ + {8, 672}, /* J */ + {8, 688}, /* K */ + {8, 704}, /* L */ + {8, 720}, /* M */ + {8, 736}, /* N */ + {8, 752}, /* O */ + {8, 768}, /* P */ + {8, 784}, /* Q */ + {8, 800}, /* R */ + {8, 816}, /* S */ + {8, 832}, /* T */ + {8, 848}, /* U */ + {8, 864}, /* V */ + {8, 880}, /* W */ + {8, 896}, /* X */ + {8, 912}, /* Y */ + {8, 928}, /* Z */ + {8, 944}, /* [ */ + {8, 960}, /* \ */ + {8, 976}, /* ] */ + {8, 992}, /* ^ */ + {8, 1008}, /* _ */ + {8, 1024}, /* ` */ + {8, 1040}, /* a */ + {8, 1056}, /* b */ + {8, 1072}, /* c */ + {8, 1088}, /* d */ + {8, 1104}, /* e */ + {8, 1120}, /* f */ + {8, 1136}, /* g */ + {8, 1152}, /* h */ + {8, 1168}, /* i */ + {8, 1184}, /* j */ + {8, 1200}, /* k */ + {8, 1216}, /* l */ + {8, 1232}, /* m */ + {8, 1248}, /* n */ + {8, 1264}, /* o */ + {8, 1280}, /* p */ + {8, 1296}, /* q */ + {8, 1312}, /* r */ + {8, 1328}, /* s */ + {8, 1344}, /* t */ + {8, 1360}, /* u */ + {8, 1376}, /* v */ + {8, 1392}, /* w */ + {8, 1408}, /* x */ + {8, 1424}, /* y */ + {8, 1440}, /* z */ + {8, 1456}, /* { */ + {8, 1472}, /* | */ + {8, 1488}, /* } */ + {8, 1504}, /* ~ */ +}; + +/* Font information for Bitstream Vera Sans Mono 9pt */ +const FONT_INFO bitstreamVeraSansMono9ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + bitstreamVeraSansMono9ptCharDescriptors, /* Character decriptor array */ + bitstreamVeraSansMono9ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/veramono9.h b/drivers/lcd/tft/fonts/veramono9.h new file mode 100644 index 0000000..96c82c6 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramono9.h @@ -0,0 +1,11 @@ +#ifndef __VERA_MONO_9__ +#define __VERA_MONO_9__ + +#include "bitmapfonts.h" + +/* Font data for Bitstream Vera Sans Mono 9pt */ +extern const uint8_t bitstreamVeraSansMono9ptCharBitmaps[]; +extern const FONT_CHAR_INFO bitstreamVeraSansMono9ptCharDescriptors[]; +extern const FONT_INFO bitstreamVeraSansMono9ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/veramonobold11.c b/drivers/lcd/tft/fonts/veramonobold11.c new file mode 100644 index 0000000..d1abeb8 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramonobold11.c @@ -0,0 +1,1164 @@ +#include "veramonobold11.h" + +/* +** Font data for Bitstream Vera Sans Mono Bold 11pt +*/ + +/* Character bitmaps for Bitstream Vera Sans Mono Bold 11pt */ +const uint8_t bitstreamVeraSansMonoBold11ptCharBitmaps[] = +{ + /* @0 ' ' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @18 '!' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0D, 0xFE, /* ## ######## */ + 0x0D, 0xFE, /* ## ######## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @36 '"' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + + /* @54 '#' (9 pixels wide) */ + 0x01, 0x00, /* # */ + 0x0F, 0x10, /* #### # */ + 0x0F, 0xF0, /* ######## */ + 0x01, 0xFE, /* ######## */ + 0x0D, 0x1E, /* ## # #### */ + 0x0F, 0xF0, /* ######## */ + 0x01, 0xFC, /* ####### */ + 0x01, 0x1E, /* # #### */ + 0x00, 0x10, /* # */ + + /* @72 '$' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x38, /* # ### */ + 0x0C, 0x7C, /* ## ##### */ + 0x08, 0x64, /* # ## # */ + 0x3F, 0xFF, /* ############## */ + 0x08, 0xC4, /* # ## # */ + 0x0F, 0xCC, /* ###### ## */ + 0x07, 0x80, /* #### */ + 0x00, 0x00, /* */ + + /* @90 '%' (9 pixels wide) */ + 0x00, 0x9C, /* # ### */ + 0x00, 0xA2, /* # # # */ + 0x00, 0xA2, /* # # # */ + 0x00, 0x62, /* ## # */ + 0x07, 0x5C, /* ### # ### */ + 0x08, 0xC0, /* # ## */ + 0x08, 0xC0, /* # ## */ + 0x08, 0xA0, /* # # # */ + 0x07, 0x20, /* ### # */ + + /* @108 '&' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x80, /* #### */ + 0x0F, 0xEC, /* ####### ## */ + 0x0C, 0x7E, /* ## ###### */ + 0x0B, 0xE2, /* # ##### # */ + 0x0F, 0x82, /* ##### # */ + 0x0F, 0xC0, /* ###### */ + 0x09, 0xC0, /* # ### */ + 0x00, 0x00, /* */ + + /* @126 ''' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x1E, /* #### */ + 0x00, 0x1E, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 '(' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x07, 0xF0, /* ####### */ + 0x1F, 0xFC, /* ########### */ + 0x38, 0x0E, /* ### ### */ + 0x20, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @162 ')' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x02, /* # # */ + 0x38, 0x0E, /* ### ### */ + 0x1F, 0xFC, /* ########### */ + 0x07, 0xF0, /* ####### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @180 '*' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x24, /* # # */ + 0x00, 0x3C, /* #### */ + 0x00, 0x18, /* ## */ + 0x00, 0x7E, /* ###### */ + 0x00, 0x18, /* ## */ + 0x00, 0x3C, /* #### */ + 0x00, 0x24, /* # # */ + 0x00, 0x00, /* */ + + /* @198 '+' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x07, 0xF8, /* ######## */ + 0x07, 0xF8, /* ######## */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + + /* @216 ',' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x3E, 0x00, /* ##### */ + 0x1E, 0x00, /* #### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @234 '-' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @252 '.' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0E, 0x00, /* ### */ + 0x0E, 0x00, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @270 '/' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x00, /* # */ + 0x1C, 0x00, /* ### */ + 0x0F, 0x00, /* #### */ + 0x03, 0xC0, /* #### */ + 0x00, 0xF0, /* #### */ + 0x00, 0x3C, /* #### */ + 0x00, 0x0E, /* ### */ + 0x00, 0x02, /* # */ + + /* @288 '0' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x07, 0xFC, /* ######### */ + 0x0C, 0x06, /* ## ## */ + 0x08, 0x62, /* # ## # */ + 0x0C, 0x06, /* ## ## */ + 0x07, 0xFC, /* ######### */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @306 '1' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x08, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @324 '2' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x04, /* ## # */ + 0x0E, 0x02, /* ### # */ + 0x0F, 0x02, /* #### # */ + 0x0B, 0x82, /* # ### # */ + 0x09, 0xE2, /* # #### # */ + 0x08, 0xFC, /* # ###### */ + 0x08, 0x7C, /* # ##### */ + 0x00, 0x00, /* */ + + /* @342 '3' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x04, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x0C, 0x62, /* ## ## # */ + 0x07, 0xDE, /* ##### #### */ + 0x07, 0x9C, /* #### ### */ + 0x00, 0x00, /* */ + + /* @360 '4' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xC0, /* ### */ + 0x01, 0x60, /* # ## */ + 0x01, 0x38, /* # ### */ + 0x01, 0x0C, /* # ## */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @378 '5' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x7E, /* # ###### */ + 0x08, 0x3E, /* # ##### */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x0C, 0x62, /* ## ## # */ + 0x07, 0xC2, /* ##### # */ + 0x03, 0x80, /* ### */ + 0x00, 0x00, /* */ + + /* @396 '6' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x07, 0xFC, /* ######### */ + 0x08, 0x26, /* # # ## */ + 0x08, 0x22, /* # # # */ + 0x08, 0x22, /* # # # */ + 0x0F, 0xE4, /* ####### # */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @414 '7' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x08, 0x02, /* # # */ + 0x0F, 0x02, /* #### # */ + 0x07, 0xC2, /* ##### # */ + 0x01, 0xFA, /* ###### # */ + 0x00, 0x3E, /* ##### */ + 0x00, 0x0E, /* ### */ + 0x00, 0x00, /* */ + + /* @432 '8' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x9C, /* #### ### */ + 0x0F, 0xDE, /* ###### #### */ + 0x0C, 0x62, /* ## ## # */ + 0x08, 0x22, /* # # # */ + 0x0C, 0x62, /* ## ## # */ + 0x0F, 0xDE, /* ###### #### */ + 0x07, 0x9C, /* #### ### */ + 0x00, 0x00, /* */ + + /* @450 '9' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x7C, /* ##### */ + 0x04, 0xFE, /* # ####### */ + 0x08, 0x82, /* # # # */ + 0x08, 0x82, /* # # # */ + 0x0C, 0x82, /* ## # # */ + 0x07, 0xFC, /* ######### */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @468 ':' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0E, 0x70, /* ### ### */ + 0x0E, 0x70, /* ### ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @486 ';' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x3E, 0x70, /* ##### ### */ + 0x1E, 0x70, /* #### ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @504 '<' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x01, 0xE0, /* #### */ + 0x01, 0x20, /* # # */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x02, 0x10, /* # # */ + 0x06, 0x18, /* ## ## */ + + /* @522 '=' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + + /* @540 '>' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x06, 0x18, /* ## ## */ + 0x02, 0x10, /* # # */ + 0x03, 0x30, /* ## ## */ + 0x03, 0x30, /* ## ## */ + 0x01, 0x20, /* # # */ + 0x01, 0xE0, /* #### */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + + /* @558 '?' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x04, /* # */ + 0x00, 0x02, /* # */ + 0x0D, 0xE2, /* ## #### # */ + 0x0D, 0xF2, /* ## ##### # */ + 0x00, 0x3E, /* ##### */ + 0x00, 0x1C, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @576 '@' (9 pixels wide) */ + 0x0F, 0xE0, /* ####### */ + 0x1F, 0xF0, /* ######### */ + 0x30, 0x18, /* ## ## */ + 0x67, 0xC4, /* ## ##### # */ + 0x4F, 0xE4, /* # ####### # */ + 0x48, 0x24, /* # # # # */ + 0x6F, 0xFC, /* ## ########## */ + 0x4F, 0xF8, /* # ######### */ + 0x00, 0x00, /* */ + + /* @594 'A' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x00, /* ## */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xFE, /* ########## */ + 0x01, 0x1E, /* # #### */ + 0x07, 0xFE, /* ########## */ + 0x0F, 0xE0, /* ####### */ + 0x0C, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @612 'B' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x0F, 0xBE, /* ##### ##### */ + 0x07, 0xBC, /* #### #### */ + 0x00, 0x00, /* */ + + /* @630 'C' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xF0, /* ##### */ + 0x07, 0xFC, /* ######### */ + 0x0C, 0x06, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x04, 0x04, /* # # */ + 0x00, 0x00, /* */ + + /* @648 'D' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0C, 0x06, /* ## ## */ + 0x07, 0xFC, /* ######### */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @666 'E' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x42, /* # # # */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + + /* @684 'F' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x42, /* # # */ + 0x00, 0x02, /* # */ + 0x00, 0x00, /* */ + + /* @702 'G' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF0, /* ###### */ + 0x07, 0xFC, /* ######### */ + 0x0C, 0x06, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x08, 0x82, /* # # # */ + 0x0F, 0x82, /* ##### # */ + 0x0F, 0x84, /* ##### # */ + 0x00, 0x00, /* */ + + /* @720 'H' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @738 'I' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @756 'J' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x08, 0x02, /* # # */ + 0x0F, 0xFE, /* ########### */ + 0x07, 0xFE, /* ########## */ + 0x00, 0x00, /* */ + + /* @774 'K' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0xE0, /* ### */ + 0x00, 0xF8, /* ##### */ + 0x03, 0xDC, /* #### ### */ + 0x0F, 0x8E, /* ##### ### */ + 0x0E, 0x06, /* ### ## */ + 0x08, 0x00, /* # */ + + /* @792 'L' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @810 'M' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x7E, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x7E, /* ###### */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @828 'N' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x3E, /* ##### */ + 0x01, 0xF0, /* ##### */ + 0x0F, 0x80, /* ##### */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @846 'O' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x07, 0xFC, /* ######### */ + 0x0C, 0x06, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x0C, 0x06, /* ## ## */ + 0x07, 0xFC, /* ######### */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @864 'P' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x82, /* # # */ + 0x00, 0x82, /* # # */ + 0x00, 0xC6, /* ## ## */ + 0x00, 0xFE, /* ####### */ + 0x00, 0x7C, /* ##### */ + 0x00, 0x00, /* */ + + /* @882 'Q' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xF8, /* ####### */ + 0x07, 0xFC, /* ######### */ + 0x0C, 0x06, /* ## ## */ + 0x08, 0x02, /* # # */ + 0x1C, 0x06, /* ### ## */ + 0x3F, 0xFC, /* ############ */ + 0x03, 0xF8, /* ####### */ + 0x00, 0x00, /* */ + + /* @900 'R' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x82, /* # # */ + 0x00, 0x82, /* # # */ + 0x03, 0x82, /* ### # */ + 0x0F, 0x7E, /* #### ###### */ + 0x0E, 0x7C, /* ### ##### */ + 0x08, 0x00, /* # */ + + /* @918 'S' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0x3C, /* # #### */ + 0x08, 0x7C, /* # ##### */ + 0x08, 0x62, /* # ## # */ + 0x08, 0xE2, /* # ### # */ + 0x08, 0xC2, /* # ## # */ + 0x0F, 0xC2, /* ###### # */ + 0x07, 0x84, /* #### # */ + 0x00, 0x00, /* */ + + /* @936 'T' (9 pixels wide) */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x00, 0x00, /* */ + + /* @954 'U' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xFE, /* ########## */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x0F, 0xFE, /* ########### */ + 0x07, 0xFE, /* ########## */ + 0x00, 0x00, /* */ + + /* @972 'V' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x06, /* ## */ + 0x00, 0xFE, /* ####### */ + 0x0F, 0xF8, /* ######### */ + 0x0E, 0x00, /* ### */ + 0x0F, 0xF8, /* ######### */ + 0x00, 0xFE, /* ####### */ + 0x00, 0x06, /* ## */ + 0x00, 0x00, /* */ + + /* @990 'W' (9 pixels wide) */ + 0x00, 0x3E, /* ##### */ + 0x0F, 0xFE, /* ########### */ + 0x0E, 0x00, /* ### */ + 0x03, 0xE0, /* ##### */ + 0x00, 0x70, /* ### */ + 0x03, 0xE0, /* ##### */ + 0x0E, 0x00, /* ### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x3E, /* ##### */ + + /* @1008 'X' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x02, /* # # */ + 0x0E, 0x0E, /* ### ### */ + 0x07, 0xBC, /* #### #### */ + 0x01, 0xF0, /* ##### */ + 0x07, 0xBC, /* #### #### */ + 0x0E, 0x0E, /* ### ### */ + 0x08, 0x02, /* # # */ + 0x00, 0x00, /* */ + + /* @1026 'Y' (9 pixels wide) */ + 0x00, 0x02, /* # */ + 0x00, 0x0E, /* ### */ + 0x00, 0x7E, /* ###### */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x7E, /* ###### */ + 0x00, 0x0E, /* ### */ + 0x00, 0x02, /* # */ + 0x00, 0x00, /* */ + + /* @1044 'Z' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0x02, /* ### # */ + 0x0F, 0x02, /* #### # */ + 0x0B, 0xC2, /* # #### # */ + 0x08, 0xF2, /* # #### # */ + 0x08, 0x7A, /* # #### # */ + 0x08, 0x1E, /* # #### */ + 0x08, 0x0E, /* # ### */ + 0x00, 0x00, /* */ + + /* @1062 '[' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xFE, /* ############# */ + 0x3F, 0xFE, /* ############# */ + 0x20, 0x02, /* # # */ + 0x20, 0x02, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1080 '\' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x00, 0x0E, /* ### */ + 0x00, 0x78, /* #### */ + 0x01, 0xE0, /* #### */ + 0x07, 0x80, /* #### */ + 0x1C, 0x00, /* ### */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1098 ']' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x02, /* # # */ + 0x20, 0x02, /* # # */ + 0x3F, 0xFE, /* ############# */ + 0x3F, 0xFE, /* ############# */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1116 '^' (9 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x18, /* ## */ + 0x00, 0x0C, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x0C, /* ## */ + 0x00, 0x18, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @1134 '_' (9 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + + /* @1152 '`' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x01, /* # */ + 0x00, 0x03, /* ## */ + 0x00, 0x06, /* ## */ + 0x00, 0x04, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1170 'a' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x00, /* ### */ + 0x0F, 0xA0, /* ##### # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x0C, 0x90, /* ## # # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1188 'b' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x0F, 0xF0, /* ######## */ + 0x07, 0xE0, /* ###### */ + 0x00, 0x00, /* */ + + /* @1206 'c' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x07, 0xE0, /* ###### */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x04, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @1224 'd' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xE0, /* ###### */ + 0x0F, 0xF0, /* ######## */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x00, /* */ + + /* @1242 'e' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x07, 0xE0, /* ###### */ + 0x0C, 0x90, /* ## # # */ + 0x08, 0x90, /* # # # */ + 0x08, 0x90, /* # # # */ + 0x08, 0xF0, /* # #### */ + 0x04, 0xE0, /* # ### */ + 0x00, 0x00, /* */ + + /* @1260 'f' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xFC, /* ########## */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x12, /* # # */ + 0x00, 0x12, /* # # */ + 0x00, 0x12, /* # # */ + 0x00, 0x00, /* */ + + /* @1278 'g' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x2F, 0xF0, /* # ######## */ + 0x4C, 0x30, /* # ## ## */ + 0x48, 0x10, /* # # # */ + 0x4C, 0x30, /* # ## ## */ + 0x7F, 0xF0, /* ########### */ + 0x3F, 0xF0, /* ########## */ + 0x00, 0x00, /* */ + + /* @1296 'h' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1314 'i' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x0F, 0xF7, /* ######## ### */ + 0x0F, 0xF7, /* ######## ### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + + /* @1332 'j' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x40, 0x10, /* # # */ + 0x40, 0x10, /* # # */ + 0x7F, 0xF7, /* ########### ### */ + 0x3F, 0xF7, /* ########## ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1350 'k' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xFE, /* ########### */ + 0x0F, 0xFE, /* ########### */ + 0x00, 0xC0, /* ## */ + 0x03, 0xE0, /* ##### */ + 0x0F, 0x30, /* #### ## */ + 0x0C, 0x10, /* ## # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1368 'l' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x02, /* # */ + 0x00, 0x02, /* # */ + 0x07, 0xFE, /* ########## */ + 0x0F, 0xFE, /* ########### */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1386 'm' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + + /* @1404 'n' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xE0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1422 'o' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0xC0, /* #### */ + 0x07, 0xE0, /* ###### */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x07, 0xE0, /* ###### */ + 0x03, 0xC0, /* #### */ + 0x00, 0x00, /* */ + + /* @1440 'p' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x7F, 0xF0, /* ########### */ + 0x7F, 0xF0, /* ########### */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x0F, 0xF0, /* ######## */ + 0x07, 0xE0, /* ###### */ + 0x00, 0x00, /* */ + + /* @1458 'q' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xE0, /* ###### */ + 0x0F, 0xF0, /* ######## */ + 0x0C, 0x30, /* ## ## */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x7F, 0xF0, /* ########### */ + 0x7F, 0xF0, /* ########### */ + 0x00, 0x00, /* */ + + /* @1476 'r' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x30, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @1494 's' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x04, 0xE0, /* # ### */ + 0x08, 0xF0, /* # #### */ + 0x09, 0x90, /* # ## # */ + 0x09, 0x90, /* # ## # */ + 0x09, 0x90, /* # ## # */ + 0x0F, 0x10, /* #### # */ + 0x07, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @1512 't' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x07, 0xFC, /* ######### */ + 0x0F, 0xFC, /* ########## */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x08, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @1530 'u' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xF0, /* ####### */ + 0x0F, 0xF0, /* ######## */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x08, 0x00, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + + /* @1548 'v' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x30, /* ## */ + 0x01, 0xF0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x0C, 0x00, /* ## */ + 0x0F, 0xE0, /* ####### */ + 0x01, 0xF0, /* ##### */ + 0x00, 0x30, /* ## */ + 0x00, 0x00, /* */ + + /* @1566 'w' (9 pixels wide) */ + 0x00, 0x70, /* ### */ + 0x0F, 0xF0, /* ######## */ + 0x0F, 0x00, /* #### */ + 0x03, 0x80, /* ### */ + 0x00, 0xC0, /* ## */ + 0x03, 0x80, /* ### */ + 0x0F, 0x00, /* #### */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x70, /* ### */ + + /* @1584 'x' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x10, /* # # */ + 0x0C, 0x30, /* ## ## */ + 0x0F, 0xF0, /* ######## */ + 0x03, 0xC0, /* #### */ + 0x0F, 0xF0, /* ######## */ + 0x0E, 0x30, /* ### ## */ + 0x08, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @1602 'y' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x40, 0xF0, /* # #### */ + 0x63, 0xE0, /* ## ##### */ + 0x7F, 0x00, /* ####### */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0xF0, /* ##### */ + 0x00, 0x30, /* ## */ + 0x00, 0x00, /* */ + + /* @1620 'z' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x10, /* ## # */ + 0x0E, 0x10, /* ### # */ + 0x0B, 0x10, /* # ## # */ + 0x09, 0x90, /* # ## # */ + 0x08, 0xD0, /* # ## # */ + 0x08, 0x70, /* # ### */ + 0x08, 0x30, /* # ## */ + 0x00, 0x00, /* */ + + /* @1638 '{' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x3E, 0xFC, /* ##### ###### */ + 0x7E, 0xFE, /* ###### ####### */ + 0x40, 0x02, /* # # */ + 0x40, 0x02, /* # # */ + 0x00, 0x00, /* */ + + /* @1656 '|' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0xFF, 0xFE, /* ############### */ + 0xFF, 0xFE, /* ############### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1674 '}' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x40, 0x02, /* # # */ + 0x40, 0x02, /* # # */ + 0x7E, 0xFE, /* ###### ####### */ + 0x3E, 0xFC, /* ##### ###### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1692 '~' (9 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x80, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x00, 0xC0, /* ## */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0xC0, /* ## */ +}; + +/* Character descriptors for Bitstream Vera Sans Mono 11pt */ +/* { [Char width in bits], [Offset into bitstreamVeraSansMonoBold11ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO bitstreamVeraSansMonoBold11ptCharDescriptors[] = +{ + {9, 0}, /* */ + {9, 18}, /* ! */ + {9, 36}, /* " */ + {9, 54}, /* # */ + {9, 72}, /* $ */ + {9, 90}, /* % */ + {9, 108}, /* & */ + {9, 126}, /* ' */ + {9, 144}, /* ( */ + {9, 162}, /* ) */ + {9, 180}, /* * */ + {9, 198}, /* + */ + {9, 216}, /* , */ + {9, 234}, /* - */ + {9, 252}, /* . */ + {9, 270}, /* / */ + {9, 288}, /* 0 */ + {9, 306}, /* 1 */ + {9, 324}, /* 2 */ + {9, 342}, /* 3 */ + {9, 360}, /* 4 */ + {9, 378}, /* 5 */ + {9, 396}, /* 6 */ + {9, 414}, /* 7 */ + {9, 432}, /* 8 */ + {9, 450}, /* 9 */ + {9, 468}, /* : */ + {9, 486}, /* ; */ + {9, 504}, /* < */ + {9, 522}, /* = */ + {9, 540}, /* > */ + {9, 558}, /* ? */ + {9, 576}, /* @ */ + {9, 594}, /* A */ + {9, 612}, /* B */ + {9, 630}, /* C */ + {9, 648}, /* D */ + {9, 666}, /* E */ + {9, 684}, /* F */ + {9, 702}, /* G */ + {9, 720}, /* H */ + {9, 738}, /* I */ + {9, 756}, /* J */ + {9, 774}, /* K */ + {9, 792}, /* L */ + {9, 810}, /* M */ + {9, 828}, /* N */ + {9, 846}, /* O */ + {9, 864}, /* P */ + {9, 882}, /* Q */ + {9, 900}, /* R */ + {9, 918}, /* S */ + {9, 936}, /* T */ + {9, 954}, /* U */ + {9, 972}, /* V */ + {9, 990}, /* W */ + {9, 1008}, /* X */ + {9, 1026}, /* Y */ + {9, 1044}, /* Z */ + {9, 1062}, /* [ */ + {9, 1080}, /* \ */ + {9, 1098}, /* ] */ + {9, 1116}, /* ^ */ + {9, 1134}, /* _ */ + {9, 1152}, /* ` */ + {9, 1170}, /* a */ + {9, 1188}, /* b */ + {9, 1206}, /* c */ + {9, 1224}, /* d */ + {9, 1242}, /* e */ + {9, 1260}, /* f */ + {9, 1278}, /* g */ + {9, 1296}, /* h */ + {9, 1314}, /* i */ + {9, 1332}, /* j */ + {9, 1350}, /* k */ + {9, 1368}, /* l */ + {9, 1386}, /* m */ + {9, 1404}, /* n */ + {9, 1422}, /* o */ + {9, 1440}, /* p */ + {9, 1458}, /* q */ + {9, 1476}, /* r */ + {9, 1494}, /* s */ + {9, 1512}, /* t */ + {9, 1530}, /* u */ + {9, 1548}, /* v */ + {9, 1566}, /* w */ + {9, 1584}, /* x */ + {9, 1602}, /* y */ + {9, 1620}, /* z */ + {9, 1638}, /* { */ + {9, 1656}, /* | */ + {9, 1674}, /* } */ + {9, 1692}, /* ~ */ +}; + +/* Font information for Bitstream Vera Sans Mono 11pt */ +const FONT_INFO bitstreamVeraSansMonoBold11ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + bitstreamVeraSansMonoBold11ptCharDescriptors, /* Character decriptor array */ + bitstreamVeraSansMonoBold11ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/veramonobold11.h b/drivers/lcd/tft/fonts/veramonobold11.h new file mode 100644 index 0000000..bba19e5 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramonobold11.h @@ -0,0 +1,11 @@ +#ifndef __VERA_MONO_BOLD_11__ +#define __VERA_MONO_BOLD_11__ + +#include "bitmapfonts.h" + +/* Font data for Bitstream Vera Sans Mono Bold 11pt */ +extern const uint8_t bitstreamVeraSansMonoBold11ptCharBitmaps[]; +extern const FONT_CHAR_INFO bitstreamVeraSansMonoBold11ptCharDescriptors[]; +extern const FONT_INFO bitstreamVeraSansMonoBold11ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/fonts/veramonobold9.c b/drivers/lcd/tft/fonts/veramonobold9.c new file mode 100644 index 0000000..50a2460 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramonobold9.c @@ -0,0 +1,1069 @@ +#include "veramonobold9.h" + +/* +** Font data for Bitstream Vera Sans Mono Bold 9pt +*/ + +/* Character bitmaps for Bitstream Vera Sans Mono Bold 9pt */ +const uint8_t bitstreamVeraSansMonoBold9ptCharBitmaps[] = +{ + /* @0 ' ' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @16 '!' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1B, 0xF0, /* ## ###### */ + 0x1B, 0xF0, /* ## ###### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @32 '"' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + + /* @48 '#' (8 pixels wide) */ + 0x04, 0x00, /* # */ + 0x1C, 0x80, /* ### # */ + 0x07, 0xC0, /* ##### */ + 0x1C, 0xE0, /* ### ### */ + 0x0F, 0x80, /* ##### */ + 0x04, 0xE0, /* # ### */ + 0x00, 0x80, /* # */ + 0x00, 0x00, /* */ + + /* @64 '$' (8 pixels wide) */ + 0x08, 0xC0, /* # ## */ + 0x19, 0xE0, /* ## #### */ + 0x11, 0x20, /* # # # */ + 0x7F, 0xF0, /* ########### */ + 0x11, 0x20, /* # # # */ + 0x1F, 0x60, /* ##### ## */ + 0x0E, 0x00, /* ### */ + 0x00, 0x00, /* */ + + /* @80 '%' (8 pixels wide) */ + 0x02, 0x60, /* # ## */ + 0x02, 0x90, /* # # # */ + 0x02, 0x90, /* # # # */ + 0x0D, 0x60, /* ## # ## */ + 0x13, 0x00, /* # ## */ + 0x12, 0x80, /* # # # */ + 0x0C, 0x80, /* ## # */ + 0x00, 0x00, /* */ + + /* @96 '&' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0x00, /* ### */ + 0x1F, 0x70, /* ##### ### */ + 0x11, 0xF0, /* # ##### */ + 0x1F, 0x10, /* ##### # */ + 0x1C, 0x00, /* ### */ + 0x17, 0x00, /* # ### */ + 0x00, 0x00, /* */ + + /* @112 ''' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x70, /* ### */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @128 '(' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x1F, 0xF0, /* ######### */ + 0x30, 0x18, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @144 ')' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x30, 0x18, /* ## ## */ + 0x1F, 0xF0, /* ######### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @160 '*' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x20, /* # # */ + 0x00, 0xC0, /* ## */ + 0x03, 0xF0, /* ###### */ + 0x00, 0xC0, /* ## */ + 0x01, 0x20, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @176 '+' (8 pixels wide) */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @192 ',' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x38, 0x00, /* ### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @208 '-' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @224 '.' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @240 '/' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x00, /* # */ + 0x18, 0x00, /* ## */ + 0x06, 0x00, /* ## */ + 0x01, 0x80, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @256 '0' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x1F, 0xF0, /* ######### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @272 '1' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @288 '2' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x20, /* ## # */ + 0x1C, 0x10, /* ### # */ + 0x16, 0x10, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x11, 0xF0, /* # ##### */ + 0x10, 0xE0, /* # ### */ + 0x00, 0x00, /* */ + + /* @304 '3' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x20, /* # # */ + 0x10, 0x10, /* # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1E, 0xF0, /* #### #### */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @320 '4' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x00, /* ### */ + 0x05, 0x80, /* # ## */ + 0x04, 0x60, /* # ## */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @336 '5' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0xF0, /* # #### */ + 0x10, 0xF0, /* # #### */ + 0x10, 0x90, /* # # # */ + 0x11, 0x90, /* # ## # */ + 0x1F, 0x90, /* ###### # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @352 '6' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0xB0, /* # # ## */ + 0x10, 0x90, /* # # # */ + 0x1F, 0x90, /* ###### # */ + 0x0F, 0x00, /* #### */ + 0x00, 0x00, /* */ + + /* @368 '7' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x10, 0x10, /* # # */ + 0x1E, 0x10, /* #### # */ + 0x0F, 0xD0, /* ###### # */ + 0x01, 0xF0, /* ##### */ + 0x00, 0x70, /* ### */ + 0x00, 0x00, /* */ + + /* @384 '8' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0E, 0xE0, /* ### ### */ + 0x1E, 0xF0, /* #### #### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1E, 0xF0, /* #### #### */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @400 '9' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0xE0, /* #### */ + 0x13, 0xF0, /* # ###### */ + 0x12, 0x10, /* # # # */ + 0x1A, 0x10, /* ## # # */ + 0x1F, 0xF0, /* ######### */ + 0x07, 0xE0, /* ###### */ + 0x00, 0x00, /* */ + + /* @416 ':' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x19, 0x80, /* ## ## */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @432 ';' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x40, 0x00, /* # */ + 0x39, 0x80, /* ### ## */ + 0x19, 0x80, /* ## ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @448 '<' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x07, 0x80, /* #### */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x0C, 0xC0, /* ## ## */ + 0x00, 0x00, /* */ + + /* @464 '=' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x05, 0x00, /* # # */ + 0x00, 0x00, /* */ + + /* @480 '>' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0xC0, /* ## ## */ + 0x04, 0x80, /* # # */ + 0x04, 0x80, /* # # */ + 0x07, 0x80, /* #### */ + 0x03, 0x00, /* ## */ + 0x03, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @496 '?' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x20, /* # */ + 0x1B, 0x10, /* ## ## # */ + 0x1B, 0x90, /* ## ### # */ + 0x00, 0xF0, /* #### */ + 0x00, 0x60, /* ## */ + 0x00, 0x00, /* */ + + /* @512 '@' (8 pixels wide) */ + 0x0F, 0x80, /* ##### */ + 0x30, 0xC0, /* ## ## */ + 0x6F, 0x20, /* ## #### # */ + 0x50, 0xA0, /* # # # # */ + 0x50, 0xA0, /* # # # # */ + 0x50, 0xA0, /* # # # # */ + 0x7F, 0xC0, /* ######### */ + 0x00, 0x00, /* */ + + /* @528 'A' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x00, /* ## */ + 0x1F, 0x80, /* ###### */ + 0x05, 0xF0, /* # ##### */ + 0x05, 0xF0, /* # ##### */ + 0x1F, 0x80, /* ###### */ + 0x18, 0x00, /* ## */ + 0x00, 0x00, /* */ + + /* @544 'B' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x1E, 0xF0, /* #### #### */ + 0x0E, 0xE0, /* ### ### */ + 0x00, 0x00, /* */ + + /* @560 'C' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x08, 0x20, /* # # */ + 0x00, 0x00, /* */ + + /* @576 'D' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x18, 0x30, /* ## ## */ + 0x0F, 0xE0, /* ####### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @592 'E' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x11, 0x10, /* # # # */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @608 'F' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @624 'G' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x0F, 0xE0, /* ####### */ + 0x18, 0x30, /* ## ## */ + 0x12, 0x10, /* # # # */ + 0x1E, 0x10, /* #### # */ + 0x1E, 0x20, /* #### # */ + 0x00, 0x00, /* */ + + /* @640 'H' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @656 'I' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @672 'J' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + + /* @688 'K' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x80, /* ## */ + 0x03, 0xC0, /* #### */ + 0x0E, 0x70, /* ### ### */ + 0x18, 0x30, /* ## ## */ + 0x10, 0x00, /* # */ + + /* @704 'L' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @720 'M' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xE0, /* ######## */ + 0x01, 0xC0, /* ### */ + 0x01, 0xC0, /* ### */ + 0x1F, 0xE0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @736 'N' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0xE0, /* #### */ + 0x0F, 0x00, /* #### */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x00, /* */ + + /* @752 'O' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x1F, 0xF0, /* ######### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @768 'P' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x01, 0x10, /* # # */ + 0x01, 0xF0, /* ##### */ + 0x00, 0xE0, /* ### */ + 0x00, 0x00, /* */ + + /* @784 'Q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0xC0, /* ##### */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x10, /* # # */ + 0x10, 0x10, /* # # */ + 0x3F, 0xF0, /* ########## */ + 0x07, 0xC0, /* ##### */ + 0x00, 0x00, /* */ + + /* @800 'R' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0x10, /* # # */ + 0x03, 0x10, /* ## # */ + 0x0E, 0xF0, /* ### #### */ + 0x1C, 0xE0, /* ### ### */ + 0x10, 0x00, /* # */ + + /* @816 'S' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x08, 0xE0, /* # ### */ + 0x11, 0xF0, /* # ##### */ + 0x11, 0x90, /* # ## # */ + 0x13, 0x10, /* # ## # */ + 0x1F, 0x10, /* ##### # */ + 0x0E, 0x20, /* ### # */ + 0x00, 0x00, /* */ + + /* @832 'T' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF0, /* ######### */ + 0x00, 0x10, /* # */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + + /* @848 'U' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xF0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x0F, 0xF0, /* ######## */ + 0x00, 0x00, /* */ + + /* @864 'V' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x30, /* ## */ + 0x07, 0xF0, /* ####### */ + 0x1F, 0x00, /* ##### */ + 0x1F, 0x00, /* ##### */ + 0x07, 0xF0, /* ####### */ + 0x00, 0x30, /* ## */ + 0x00, 0x00, /* */ + + /* @880 'W' (8 pixels wide) */ + 0x00, 0xF0, /* #### */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0x00, /* ##### */ + 0x00, 0xC0, /* ## */ + 0x1F, 0x00, /* ##### */ + 0x1F, 0xF0, /* ######### */ + 0x01, 0xF0, /* ##### */ + 0x00, 0x00, /* */ + + /* @896 'X' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x10, /* # # */ + 0x1C, 0x70, /* ### ### */ + 0x07, 0xC0, /* ##### */ + 0x07, 0xC0, /* ##### */ + 0x1C, 0x70, /* ### ### */ + 0x10, 0x10, /* # # */ + 0x00, 0x00, /* */ + + /* @912 'Y' (8 pixels wide) */ + 0x00, 0x10, /* # */ + 0x00, 0x70, /* ### */ + 0x01, 0xE0, /* #### */ + 0x1F, 0x80, /* ###### */ + 0x1F, 0x80, /* ###### */ + 0x01, 0xE0, /* #### */ + 0x00, 0x70, /* ### */ + 0x00, 0x10, /* # */ + + /* @928 'Z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x10, /* ## # */ + 0x1E, 0x10, /* #### # */ + 0x17, 0x10, /* # ### # */ + 0x11, 0xD0, /* # ### # */ + 0x10, 0xF0, /* # #### */ + 0x10, 0x30, /* # ## */ + 0x00, 0x00, /* */ + + /* @944 '[' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x3F, 0xF8, /* ########### */ + 0x3F, 0xF8, /* ########### */ + 0x20, 0x08, /* # # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @960 '\' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x10, /* # */ + 0x00, 0x70, /* ### */ + 0x01, 0x80, /* ## */ + 0x06, 0x00, /* ## */ + 0x38, 0x00, /* ### */ + 0x20, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @976 ']' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x20, 0x08, /* # # */ + 0x3F, 0xF8, /* ########### */ + 0x3F, 0xF8, /* ########### */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @992 '^' (8 pixels wide) */ + 0x00, 0x40, /* # */ + 0x00, 0x60, /* ## */ + 0x00, 0x30, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x30, /* ## */ + 0x00, 0x60, /* ## */ + 0x00, 0x40, /* # */ + 0x00, 0x00, /* */ + + /* @1008 '_' (8 pixels wide) */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x80, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1024 '`' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x08, /* # */ + 0x00, 0x18, /* ## */ + 0x00, 0x10, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1040 'a' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0C, 0x00, /* ## */ + 0x1E, 0x80, /* #### # */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + + /* @1056 'b' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + + /* @1072 'c' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x07, 0x00, /* ### */ + 0x0F, 0x80, /* ##### */ + 0x18, 0xC0, /* ## ## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x08, 0x80, /* # # */ + 0x00, 0x00, /* */ + + /* @1088 'd' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x00, /* */ + + /* @1104 'e' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x12, 0x40, /* # # # */ + 0x12, 0x40, /* # # # */ + 0x13, 0xC0, /* # #### */ + 0x0B, 0x80, /* # ### */ + 0x00, 0x00, /* */ + + /* @1120 'f' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xF0, /* ######### */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x48, /* # # */ + 0x00, 0x48, /* # # */ + 0x00, 0x00, /* */ + + /* @1136 'g' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x9F, 0xC0, /* # ####### */ + 0x90, 0x40, /* # # # */ + 0x90, 0x40, /* # # # */ + 0xFF, 0xC0, /* ########## */ + 0x7F, 0xC0, /* ######### */ + 0x00, 0x00, /* */ + + /* @1152 'h' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + + /* @1168 'i' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xD8, /* ####### ## */ + 0x1F, 0xD8, /* ####### ## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1184 'j' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x80, 0x40, /* # # */ + 0x80, 0x40, /* # # */ + 0xFF, 0xD8, /* ########## ## */ + 0x7F, 0xD8, /* ######### ## */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1200 'k' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xF8, /* ########## */ + 0x1F, 0xF8, /* ########## */ + 0x03, 0x00, /* ## */ + 0x0F, 0x80, /* ##### */ + 0x1C, 0xC0, /* ### ## */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1216 'l' (8 pixels wide) */ + 0x00, 0x08, /* # */ + 0x00, 0x08, /* # */ + 0x0F, 0xF8, /* ######### */ + 0x1F, 0xF8, /* ########## */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1232 'm' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1248 'n' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0x80, /* ###### */ + 0x00, 0x00, /* */ + + /* @1264 'o' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + + /* @1280 'p' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0xFF, 0xC0, /* ########## */ + 0xFF, 0xC0, /* ########## */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x1F, 0xC0, /* ####### */ + 0x0F, 0x80, /* ##### */ + 0x00, 0x00, /* */ + + /* @1296 'q' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0x80, /* ##### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0xFF, 0xC0, /* ########## */ + 0xFF, 0xC0, /* ########## */ + 0x00, 0x00, /* */ + + /* @1312 'r' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x00, 0x00, /* */ + + /* @1328 's' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x09, 0x80, /* # ## */ + 0x13, 0xC0, /* # #### */ + 0x13, 0x40, /* # ## # */ + 0x12, 0x40, /* # # # */ + 0x1E, 0x40, /* #### # */ + 0x0C, 0x80, /* ## # */ + 0x00, 0x00, /* */ + + /* @1344 't' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x40, /* # */ + 0x00, 0x40, /* # */ + 0x0F, 0xF0, /* ######## */ + 0x1F, 0xF0, /* ######### */ + 0x10, 0x40, /* # # */ + 0x10, 0x40, /* # # */ + 0x00, 0x00, /* */ + + /* @1360 'u' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x0F, 0xC0, /* ###### */ + 0x1F, 0xC0, /* ####### */ + 0x10, 0x00, /* # */ + 0x10, 0x00, /* # */ + 0x1F, 0xC0, /* ####### */ + 0x1F, 0xC0, /* ####### */ + 0x00, 0x00, /* */ + + /* @1376 'v' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0xC0, /* ## */ + 0x07, 0xC0, /* ##### */ + 0x1E, 0x00, /* #### */ + 0x1E, 0x00, /* #### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x00, /* */ + + /* @1392 'w' (8 pixels wide) */ + 0x01, 0xC0, /* ### */ + 0x1F, 0xC0, /* ####### */ + 0x1E, 0x00, /* #### */ + 0x01, 0x00, /* # */ + 0x1E, 0x00, /* #### */ + 0x1F, 0xC0, /* ####### */ + 0x01, 0xC0, /* ### */ + 0x00, 0x00, /* */ + + /* @1408 'x' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x10, 0x40, /* # # */ + 0x1D, 0xC0, /* ### ### */ + 0x0F, 0x80, /* ##### */ + 0x0F, 0x80, /* ##### */ + 0x1D, 0xC0, /* ### ### */ + 0x10, 0x40, /* # # */ + 0x00, 0x00, /* */ + + /* @1424 'y' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x80, 0xC0, /* # ## */ + 0x87, 0xC0, /* # ##### */ + 0xFE, 0x00, /* ####### */ + 0x3E, 0x00, /* ##### */ + 0x07, 0xC0, /* ##### */ + 0x00, 0xC0, /* ## */ + 0x00, 0x00, /* */ + + /* @1440 'z' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x18, 0x40, /* ## # */ + 0x1C, 0x40, /* ### # */ + 0x16, 0x40, /* # ## # */ + 0x13, 0x40, /* # ## # */ + 0x11, 0xC0, /* # ### */ + 0x10, 0xC0, /* # ## */ + 0x00, 0x00, /* */ + + /* @1456 '{' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x1E, 0xF8, /* #### ##### */ + 0x3E, 0xF8, /* ##### ##### */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x00, 0x00, /* */ + + /* @1472 '|' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x7F, 0xF8, /* ############ */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + 0x00, 0x00, /* */ + + /* @1488 '}' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x20, 0x08, /* # # */ + 0x20, 0x08, /* # # */ + 0x3E, 0xF8, /* ##### ##### */ + 0x3E, 0xF8, /* ##### ##### */ + 0x01, 0x00, /* # */ + 0x01, 0x00, /* # */ + 0x00, 0x00, /* */ + + /* @1504 '~' (8 pixels wide) */ + 0x00, 0x00, /* */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x02, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x04, 0x00, /* # */ + 0x00, 0x00, /* */ +}; + +/* Character descriptors for Bitstream Vera Sans Mono 9pt */ +/* { [Char width in bits], [Offset into bitstreamVeraSansMonoBold9ptCharBitmaps in bytes] } */ +const FONT_CHAR_INFO bitstreamVeraSansMonoBold9ptCharDescriptors[] = +{ + {8, 0}, /* */ + {8, 16}, /* ! */ + {8, 32}, /* " */ + {8, 48}, /* # */ + {8, 64}, /* $ */ + {8, 80}, /* % */ + {8, 96}, /* & */ + {8, 112}, /* ' */ + {8, 128}, /* ( */ + {8, 144}, /* ) */ + {8, 160}, /* * */ + {8, 176}, /* + */ + {8, 192}, /* , */ + {8, 208}, /* - */ + {8, 224}, /* . */ + {8, 240}, /* / */ + {8, 256}, /* 0 */ + {8, 272}, /* 1 */ + {8, 288}, /* 2 */ + {8, 304}, /* 3 */ + {8, 320}, /* 4 */ + {8, 336}, /* 5 */ + {8, 352}, /* 6 */ + {8, 368}, /* 7 */ + {8, 384}, /* 8 */ + {8, 400}, /* 9 */ + {8, 416}, /* : */ + {8, 432}, /* ; */ + {8, 448}, /* < */ + {8, 464}, /* = */ + {8, 480}, /* > */ + {8, 496}, /* ? */ + {8, 512}, /* @ */ + {8, 528}, /* A */ + {8, 544}, /* B */ + {8, 560}, /* C */ + {8, 576}, /* D */ + {8, 592}, /* E */ + {8, 608}, /* F */ + {8, 624}, /* G */ + {8, 640}, /* H */ + {8, 656}, /* I */ + {8, 672}, /* J */ + {8, 688}, /* K */ + {8, 704}, /* L */ + {8, 720}, /* M */ + {8, 736}, /* N */ + {8, 752}, /* O */ + {8, 768}, /* P */ + {8, 784}, /* Q */ + {8, 800}, /* R */ + {8, 816}, /* S */ + {8, 832}, /* T */ + {8, 848}, /* U */ + {8, 864}, /* V */ + {8, 880}, /* W */ + {8, 896}, /* X */ + {8, 912}, /* Y */ + {8, 928}, /* Z */ + {8, 944}, /* [ */ + {8, 960}, /* \ */ + {8, 976}, /* ] */ + {8, 992}, /* ^ */ + {8, 1008}, /* _ */ + {8, 1024}, /* ` */ + {8, 1040}, /* a */ + {8, 1056}, /* b */ + {8, 1072}, /* c */ + {8, 1088}, /* d */ + {8, 1104}, /* e */ + {8, 1120}, /* f */ + {8, 1136}, /* g */ + {8, 1152}, /* h */ + {8, 1168}, /* i */ + {8, 1184}, /* j */ + {8, 1200}, /* k */ + {8, 1216}, /* l */ + {8, 1232}, /* m */ + {8, 1248}, /* n */ + {8, 1264}, /* o */ + {8, 1280}, /* p */ + {8, 1296}, /* q */ + {8, 1312}, /* r */ + {8, 1328}, /* s */ + {8, 1344}, /* t */ + {8, 1360}, /* u */ + {8, 1376}, /* v */ + {8, 1392}, /* w */ + {8, 1408}, /* x */ + {8, 1424}, /* y */ + {8, 1440}, /* z */ + {8, 1456}, /* { */ + {8, 1472}, /* | */ + {8, 1488}, /* } */ + {8, 1504}, /* ~ */ +}; + +/* Font information for Bitstream Vera Sans Mono 9pt */ +const FONT_INFO bitstreamVeraSansMonoBold9ptFontInfo = +{ + 2, /* Character height */ + ' ', /* Start character */ + bitstreamVeraSansMonoBold9ptCharDescriptors, /* Character decriptor array */ + bitstreamVeraSansMonoBold9ptCharBitmaps, /* Character bitmap array */ +}; diff --git a/drivers/lcd/tft/fonts/veramonobold9.h b/drivers/lcd/tft/fonts/veramonobold9.h new file mode 100644 index 0000000..3b73134 --- /dev/null +++ b/drivers/lcd/tft/fonts/veramonobold9.h @@ -0,0 +1,11 @@ +#ifndef __VERA_MONO_BOLD_9__ +#define __VERA_MONO_BOLD_9__ + +#include "bitmapfonts.h" + +/* Font data for Bitstream Vera Sans Mono Bold 9pt */ +extern const uint8_t bitstreamVeraSansMonoBold9ptCharBitmaps[]; +extern const FONT_CHAR_INFO bitstreamVeraSansMonoBold9ptCharDescriptors[]; +extern const FONT_INFO bitstreamVeraSansMonoBold9ptFontInfo; + +#endif \ No newline at end of file diff --git a/drivers/lcd/tft/hw/ILI9325.c b/drivers/lcd/tft/hw/ILI9325.c new file mode 100644 index 0000000..d7fc0e1 --- /dev/null +++ b/drivers/lcd/tft/hw/ILI9325.c @@ -0,0 +1,624 @@ +/**************************************************************************/ +/*! + @file ILI9325.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for ILI9325 240x320 pixel TFT LCD displays. + + This driver uses an 8-bit interface and a 16-bit RGB565 colour palette. + Should also work with SPFD5408B or OTM3225A-based LCDs, though + there are sometimes minor differences (for example vertical scrolling + via register 0x6A isn't supported on all controllers). + + @section UPDATES + + 26-11-2010: ili9325ReadData contributed by Adafruit Industries + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "ILI9325.h" +#include "core/systick/systick.h" +#include "drivers/lcd/tft/touchscreen.h" + +static lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT; +static lcdProperties_t ili9325Properties = { 240, 320, TRUE, TRUE, TRUE }; + +/*************************************************/ +/* Private Methods */ +/*************************************************/ + +/**************************************************************************/ +/*! + @brief Causes a brief delay (10 ticks per unit) +*/ +/**************************************************************************/ +void ili9325Delay(unsigned int t) +{ + unsigned char t1; + while(t--) + for ( t1=10; t1 > 0; t1-- ) + { + __asm("nop"); + } +} + +/**************************************************************************/ +/*! + @brief Writes the supplied 16-bit command using an 8-bit interface +*/ +/**************************************************************************/ +void ili9325WriteCmd(uint16_t command) +{ + // Compiled with -Os on GCC 4.4 this works out to 25 cycles + // (versus 36 compiled with no optimisations). I'm not sure it + // can be improved further, so that means 25 cycles/350nS for + // continuous writes (cmd, data, data, data, ...) or ~150 cycles/ + // ~2.1uS for a random pixel (Set X [cmd+data], Set Y [cmd+data], + // Set color [cmd+data]) (times assumes 72MHz clock). + + CLR_CS_CD_SET_RD_WR; // Saves 18 commands compared to "CLR_CS; CLR_CD; SET_RD; SET_WR;" + ILI9325_GPIO2DATA_DATA = (command >> (8 - ILI9325_DATA_OFFSET)); + CLR_WR; + SET_WR; + ILI9325_GPIO2DATA_DATA = command << ILI9325_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR; SET_CS;" +} + +/**************************************************************************/ +/*! + @brief Writes the supplied 16-bit data using an 8-bit interface +*/ +/**************************************************************************/ +void ili9325WriteData(uint16_t data) +{ + CLR_CS_SET_CD_RD_WR; // Saves 18 commands compared to SET_CD; SET_RD; SET_WR; CLR_CS" + ILI9325_GPIO2DATA_DATA = (data >> (8 - ILI9325_DATA_OFFSET)); + CLR_WR; + SET_WR; + ILI9325_GPIO2DATA_DATA = data << ILI9325_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR, SET_CS;" +} + +/**************************************************************************/ +/*! + @brief Reads a 16-bit value from the 8-bit data bus +*/ +/**************************************************************************/ +uint16_t ili9325ReadData(void) +{ + // ToDo: Optimise this method! + + uint16_t high, low; + high = low = 0; + uint16_t d; + + SET_CD_RD_WR; // Saves 14 commands compared to "SET_CD; SET_RD; SET_WR" + CLR_CS; + + // set inputs + ILI9325_GPIO2DATA_SETINPUT; + CLR_RD; + ili9325Delay(100); + high = ILI9325_GPIO2DATA_DATA; + high >>= ILI9325_DATA_OFFSET; + high &= 0xFF; + SET_RD; + + CLR_RD; + ili9325Delay(100); + low = ILI9325_GPIO2DATA_DATA; + low >>= ILI9325_DATA_OFFSET; + low &=0xFF; + SET_RD; + + SET_CS; + ILI9325_GPIO2DATA_SETOUTPUT; + + d = high; + d <<= 8; + d |= low; + + return d; +} + +/**************************************************************************/ +/*! + @brief Reads a 16-bit value +*/ +/**************************************************************************/ +uint16_t ili9325Read(uint16_t addr) +{ + ili9325WriteCmd(addr); + return ili9325ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sends a 16-bit command + 16-bit data +*/ +/**************************************************************************/ +void ili9325Command(uint16_t command, uint16_t data) +{ + ili9325WriteCmd(command); + ili9325WriteData(data); +} + +/**************************************************************************/ +/*! + @brief Returns the 16-bit (4-hexdigit) controller code +*/ +/**************************************************************************/ +uint16_t ili9325Type(void) +{ + ili9325WriteCmd(ILI9325_COMMANDS_DRIVERCODEREAD); + return ili9325ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sets the cursor to the specified X/Y position +*/ +/**************************************************************************/ +void ili9325SetCursor(uint16_t x, uint16_t y) +{ + uint16_t al, ah; + + if (lcdOrientation == LCD_ORIENTATION_LANDSCAPE) + { + al = y; + ah = x; + } + else + { + al = x; + ah = y; + } + + ili9325Command(ILI9325_COMMANDS_HORIZONTALGRAMADDRESSSET, al); + ili9325Command(ILI9325_COMMANDS_VERTICALGRAMADDRESSSET, ah); +} + +/**************************************************************************/ +/*! + @brief Sends the initialisation sequence to the display controller +*/ +/**************************************************************************/ +void ili9325InitDisplay(void) +{ + // Clear data line + GPIO_GPIO2DATA &= ~ILI9325_DATA_MASK; + + SET_RD; + SET_WR; + SET_CS; + SET_CD; + + // Reset display + CLR_RESET; + ili9325Delay(10000); + SET_RESET; + ili9325Delay(500); + + ili9325Command(ILI9325_COMMANDS_DRIVEROUTPUTCONTROL1, 0x0100); // Driver Output Control Register (R01h) + ili9325Command(ILI9325_COMMANDS_LCDDRIVINGCONTROL, 0x0700); // LCD Driving Waveform Control (R02h) + ili9325Command(ILI9325_COMMANDS_ENTRYMODE, 0x1030); // Entry Mode (R03h) + ili9325Command(ILI9325_COMMANDS_DISPLAYCONTROL2, 0x0302); + ili9325Command(ILI9325_COMMANDS_DISPLAYCONTROL3, 0x0000); + ili9325Command(ILI9325_COMMANDS_DISPLAYCONTROL4, 0x0000); // Fmark On + ili9325Command(ILI9325_COMMANDS_POWERCONTROL1, 0x0000); // Power Control 1 (R10h) + ili9325Command(ILI9325_COMMANDS_POWERCONTROL2, 0x0007); // Power Control 2 (R11h) + ili9325Command(ILI9325_COMMANDS_POWERCONTROL3, 0x0000); // Power Control 3 (R12h) + ili9325Command(ILI9325_COMMANDS_POWERCONTROL4, 0x0000); // Power Control 4 (R13h) + ili9325Delay(1000); + ili9325Command(ILI9325_COMMANDS_POWERCONTROL1, 0x14B0); // Power Control 1 (R10h) + ili9325Delay(500); + ili9325Command(ILI9325_COMMANDS_POWERCONTROL2, 0x0007); // Power Control 2 (R11h) + ili9325Delay(500); + ili9325Command(ILI9325_COMMANDS_POWERCONTROL3, 0x008E); // Power Control 3 (R12h) + ili9325Command(ILI9325_COMMANDS_POWERCONTROL4, 0x0C00); // Power Control 4 (R13h) + ili9325Command(ILI9325_COMMANDS_POWERCONTROL7, 0x0015); // NVM read data 2 (R29h) + ili9325Delay(500); + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL1, 0x0000); // Gamma Control 1 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL2, 0x0107); // Gamma Control 2 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL3, 0x0000); // Gamma Control 3 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL4, 0x0203); // Gamma Control 4 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL5, 0x0402); // Gamma Control 5 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL6, 0x0000); // Gamma Control 6 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL7, 0x0207); // Gamma Control 7 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL8, 0x0000); // Gamma Control 8 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL9, 0x0203); // Gamma Control 9 + ili9325Command(ILI9325_COMMANDS_GAMMACONTROL10, 0x0403); // Gamma Control 10 + ili9325Command(ILI9325_COMMANDS_HORIZONTALADDRESSSTARTPOSITION, 0x0000); // Window Horizontal RAM Address Start (R50h) + ili9325Command(ILI9325_COMMANDS_HORIZONTALADDRESSENDPOSITION, ili9325Properties.width - 1); // Window Horizontal RAM Address End (R51h) + ili9325Command(ILI9325_COMMANDS_VERTICALADDRESSSTARTPOSITION, 0X0000); // Window Vertical RAM Address Start (R52h) + ili9325Command(ILI9325_COMMANDS_VERTICALADDRESSENDPOSITION, ili9325Properties.height - 1); // Window Vertical RAM Address End (R53h) + ili9325Command(ILI9325_COMMANDS_DRIVEROUTPUTCONTROL2, 0xa700); // Driver Output Control (R60h) + ili9325Command(ILI9325_COMMANDS_BASEIMAGEDISPLAYCONTROL, 0x0003); // Driver Output Control (R61h) - enable VLE + ili9325Command(ILI9325_COMMANDS_PANELINTERFACECONTROL1, 0X0010); // Panel Interface Control 1 (R90h) + + // Display On + ili9325Command(ILI9325_COMMANDS_DISPLAYCONTROL1, 0x0133); // Display Control (R07h) + ili9325Delay(500); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); +} + +/**************************************************************************/ +/*! + @brief Sets the cursor to the home position (0,0) +*/ +/**************************************************************************/ +void ili9325Home(void) +{ + ili9325SetCursor(0, 0); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) +} + +/**************************************************************************/ +/*! + @brief Sets the window confines +*/ +/**************************************************************************/ +void ili9325SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + ili9325Command(ILI9325_COMMANDS_HORIZONTALADDRESSSTARTPOSITION, x0); + ili9325Command(ILI9325_COMMANDS_HORIZONTALADDRESSENDPOSITION, x1); + ili9325Command(ILI9325_COMMANDS_VERTICALADDRESSSTARTPOSITION, y0); + ili9325Command(ILI9325_COMMANDS_VERTICALADDRESSENDPOSITION, y1); + ili9325SetCursor(x0, y0); +} + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +/**************************************************************************/ +/*! + @brief Configures any pins or HW and initialises the LCD controller +*/ +/**************************************************************************/ +void lcdInit(void) +{ + // Set control line pins to output + gpioSetDir(ILI9325_CS_PORT, ILI9325_CS_PIN, 1); + gpioSetDir(ILI9325_CD_PORT, ILI9325_CD_PIN, 1); + gpioSetDir(ILI9325_WR_PORT, ILI9325_WR_PIN, 1); + gpioSetDir(ILI9325_RD_PORT, ILI9325_RD_PIN, 1); + + // Set data port pins to output + ILI9325_GPIO2DATA_SETOUTPUT; + + // Disable pullups + ILI9325_DISABLEPULLUPS(); + + // Set backlight pin to output and turn it on + gpioSetDir(ILI9325_BL_PORT, ILI9325_BL_PIN, 1); // set to output + lcdBacklight(TRUE); + + // Set reset pin to output + gpioSetDir(ILI9325_RES_PORT, ILI9325_RES_PIN, 1); // Set to output + gpioSetValue(ILI9325_RES_PORT, ILI9325_RES_PIN, 0); // Low to reset + systickDelay(50); + gpioSetValue(ILI9325_RES_PORT, ILI9325_RES_PIN, 1); // High to exit + + // Initialize the display + ili9325InitDisplay(); + + systickDelay(50); + + // Set lcd to default orientation + lcdSetOrientation(lcdOrientation); + + // Fill black + lcdFillRGB(COLOR_BLACK); + + // Initialise the touch screen (and calibrate if necessary) + tsInit(); +} + +/**************************************************************************/ +/*! + @brief Enables or disables the LCD backlight +*/ +/**************************************************************************/ +void lcdBacklight(bool state) +{ + // Set the backlight + gpioSetValue(ILI9325_BL_PORT, ILI9325_BL_PIN, state ? 0 : 1); +} + +/**************************************************************************/ +/*! + @brief Renders a simple test pattern on the LCD +*/ +/**************************************************************************/ +void lcdTest(void) +{ + uint32_t i,j; + ili9325Home(); + + for(i=0;i<320;i++) + { + for(j=0;j<240;j++) + { + if(i>279)ili9325WriteData(COLOR_WHITE); + else if(i>239)ili9325WriteData(COLOR_BLUE); + else if(i>199)ili9325WriteData(COLOR_GREEN); + else if(i>159)ili9325WriteData(COLOR_CYAN); + else if(i>119)ili9325WriteData(COLOR_RED); + else if(i>79)ili9325WriteData(COLOR_MAGENTA); + else if(i>39)ili9325WriteData(COLOR_YELLOW); + else ili9325WriteData(COLOR_BLACK); + } + } +} + +/**************************************************************************/ +/*! + @brief Fills the LCD with the specified 16-bit color +*/ +/**************************************************************************/ +void lcdFillRGB(uint16_t data) +{ + unsigned int i; + ili9325Home(); + + uint32_t pixels = 320*240; + for ( i=0; i < pixels; i++ ) + { + ili9325WriteData(data); + } +} + +/**************************************************************************/ +/*! + @brief Draws a single pixel at the specified X/Y location +*/ +/**************************************************************************/ +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + ili9325SetCursor(x, y); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) + ili9325WriteData(color); +} + +/**************************************************************************/ +/*! + @brief Draws an array of consecutive RGB565 pixels (much + faster than addressing each pixel individually) +*/ +/**************************************************************************/ +void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len) +{ + uint32_t i = 0; + ili9325SetCursor(x, y); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); + do + { + ili9325WriteData(data[i]); + i++; + } while (i= lcdGetWidth()) + { + x1 = lcdGetWidth() - 1; + } + if (x0 >= lcdGetWidth()) + { + x0 = lcdGetWidth() - 1; + } + + ili9325SetCursor(x0, y); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) + for (pixels = 0; pixels < x1 - x0 + 1; pixels++) + { + ili9325WriteData(color); + } +} + +/**************************************************************************/ +/*! + @brief Optimised routine to draw a vertical line faster than + setting individual pixels +*/ +/**************************************************************************/ +void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color) +{ + // Allows for slightly better performance than setting individual pixels + lcdOrientation_t orientation = lcdOrientation; + + // Switch orientation + lcdSetOrientation(orientation == LCD_ORIENTATION_PORTRAIT ? LCD_ORIENTATION_LANDSCAPE : LCD_ORIENTATION_PORTRAIT); + + // Draw horizontal line like usual + lcdDrawHLine(y0, y1, lcdGetHeight() - (x + 1), color); + + // Switch orientation back + lcdSetOrientation(orientation); +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit color of the pixel at the specified location +*/ +/**************************************************************************/ +uint16_t lcdGetPixel(uint16_t x, uint16_t y) +{ + uint16_t preFetch = 0; + + ili9325SetCursor(x, y); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); + preFetch = ili9325ReadData(); + + // Eeek ... why does this need to be done twice for a proper value?!? + ili9325SetCursor(x, y); + ili9325WriteCmd(ILI9325_COMMANDS_WRITEDATATOGRAM); + return ili9325ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sets the LCD orientation to horizontal and vertical +*/ +/**************************************************************************/ +void lcdSetOrientation(lcdOrientation_t orientation) +{ + uint16_t entryMode = 0x1030; + uint16_t outputControl = 0x0100; + + switch (orientation) + { + case LCD_ORIENTATION_PORTRAIT: + entryMode = 0x1030; + outputControl = 0x0100; + break; + case LCD_ORIENTATION_LANDSCAPE: + entryMode = 0x1028; + outputControl = 0x0000; + break; + } + + ili9325Command(ILI9325_COMMANDS_ENTRYMODE, entryMode); + ili9325Command(ILI9325_COMMANDS_DRIVEROUTPUTCONTROL1, outputControl); + lcdOrientation = orientation; + + ili9325SetCursor(0, 0); +} + +/**************************************************************************/ +/*! + @brief Gets the current screen orientation (horizontal or vertical) +*/ +/**************************************************************************/ +lcdOrientation_t lcdGetOrientation(void) +{ + return lcdOrientation; +} + +/**************************************************************************/ +/*! + @brief Gets the width in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetWidth(void) +{ + switch (lcdOrientation) + { + case LCD_ORIENTATION_PORTRAIT: + return ili9325Properties.width; + break; + case LCD_ORIENTATION_LANDSCAPE: + default: + return ili9325Properties.height; + } +} + +/**************************************************************************/ +/*! + @brief Gets the height in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetHeight(void) +{ + switch (lcdOrientation) + { + case LCD_ORIENTATION_PORTRAIT: + return ili9325Properties.height; + break; + case LCD_ORIENTATION_LANDSCAPE: + default: + return ili9325Properties.width; + } +} + +/**************************************************************************/ +/*! + @brief Scrolls the contents of the LCD screen vertically the + specified number of pixels using a HW optimised routine +*/ +/**************************************************************************/ +void lcdScroll(int16_t pixels, uint16_t fillColor) +{ + int16_t y = pixels; + while (y < 0) + y += 320; + while (y >= 320) + y -= 320; + ili9325WriteCmd(ILI9325_COMMANDS_VERTICALSCROLLCONTROL); + ili9325WriteData(y); +} + +/**************************************************************************/ +/*! + @brief Gets the controller's 16-bit (4 hexdigit) ID +*/ +/**************************************************************************/ +uint16_t lcdGetControllerID(void) +{ + return ili9325Type(); +} + +/**************************************************************************/ +/*! + @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs + generic capabilities and dimensions +*/ +/**************************************************************************/ +lcdProperties_t lcdGetProperties(void) +{ + return ili9325Properties; +} diff --git a/drivers/lcd/tft/hw/ILI9325.h b/drivers/lcd/tft/hw/ILI9325.h new file mode 100644 index 0000000..a589c40 --- /dev/null +++ b/drivers/lcd/tft/hw/ILI9325.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/*! + @file ILI9325.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __ILI9325_H__ +#define __ILI9325_H__ + +#include "projectconfig.h" + +#include "drivers/lcd/tft/lcd.h" +#include "core/gpio/gpio.h" + +// Control pins +#define ILI9325_CS_PORT 1 // CS (LCD Pin 7) +#define ILI9325_CS_PIN 8 +#define ILI9325_CD_PORT 1 // CS/RS (LCD Pin 8) +#define ILI9325_CD_PIN 9 +#define ILI9325_WR_PORT 1 // WR (LCD Pin 9) +#define ILI9325_WR_PIN 10 +#define ILI9325_RD_PORT 1 // RD (LCD Pin 10) +#define ILI9325_RD_PIN 11 + +// These combined pin definitions are for optimisation purposes. +// If the pin values above are modified the bit equivalents +// below will also need to be updated +#define ILI9325_CS_CD_PINS 0x300 // 8 + 9 +#define ILI9325_RD_WR_PINS 0xC00 // 11 + 10 +#define ILI9325_WR_CS_PINS 0x500 // 10 + 8 +#define ILI9325_CD_RD_WR_PINS 0xE00 // 9 + 11 + 10 +#define ILI9325_CS_CD_RD_WR_PINS 0xF00 // 8 + 9 + 11 + 10 + +// Backlight and Reset pins +#define ILI9325_RES_PORT 3 // LCD Reset (LCD Pin 31) +#define ILI9325_RES_PIN 3 +#define ILI9325_BL_PORT 2 // Backlight Enable (LCD Pin 16) +#define ILI9325_BL_PIN 9 + +// Data pins +// Note: data pins must be consecutive and on the same port +#define ILI9325_DATA_PORT 2 // 8-Pin Data Port +#define ILI9325_DATA_PIN1 1 +#define ILI9325_DATA_PIN2 2 +#define ILI9325_DATA_PIN3 3 +#define ILI9325_DATA_PIN4 4 +#define ILI9325_DATA_PIN5 5 +#define ILI9325_DATA_PIN6 6 +#define ILI9325_DATA_PIN7 7 +#define ILI9325_DATA_PIN8 8 +#define ILI9325_DATA_MASK 0x000001FE +#define ILI9325_DATA_OFFSET 1 // Offset = PIN1 + +// Placed here to try to keep all pin specific values in header file +#define ILI9325_DISABLEPULLUPS() do { gpioSetPullup(&IOCON_PIO2_1, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_2, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_3, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_4, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_5, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_6, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_7, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_8, gpioPullupMode_Inactive); } while (0) + +// These registers allow fast single operation clear+set of bits (see section 8.5.1 of LPC1343 UM) +#define ILI9325_GPIO2DATA_DATA (*(pREG32 (GPIO_GPIO2_BASE + (ILI9325_DATA_MASK << 2)))) +#define ILI9325_GPIO1DATA_WR (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9325_WR_PIN) << 2)))) +#define ILI9325_GPIO1DATA_CD (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9325_CD_PIN) << 2)))) +#define ILI9325_GPIO1DATA_CS (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9325_CS_PIN) << 2)))) +#define ILI9325_GPIO1DATA_RD (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9325_RD_PIN) << 2)))) +#define ILI9325_GPIO3DATA_RES (*(pREG32 (GPIO_GPIO3_BASE + ((1 << ILI9325_RES_PIN) << 2)))) +#define ILI9325_GPIO1DATA_CS_CD (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9325_CS_CD_PINS) << 2)))) +#define ILI9325_GPIO1DATA_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9325_RD_WR_PINS) << 2)))) +#define ILI9325_GPIO1DATA_WR_CS (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9325_WR_CS_PINS) << 2)))) +#define ILI9325_GPIO1DATA_CD_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9325_CD_RD_WR_PINS) << 2)))) +#define ILI9325_GPIO1DATA_CS_CD_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9325_CS_CD_RD_WR_PINS) << 2)))) + +// Macros to set data bus direction to input/output +#define ILI9325_GPIO2DATA_SETINPUT GPIO_GPIO2DIR &= ~ILI9325_DATA_MASK +#define ILI9325_GPIO2DATA_SETOUTPUT GPIO_GPIO2DIR |= ILI9325_DATA_MASK + +// Macros for control line state +#define CLR_CD ILI9325_GPIO1DATA_CD = (0) +#define SET_CD ILI9325_GPIO1DATA_CD = (1 << ILI9325_CD_PIN) +#define CLR_CS ILI9325_GPIO1DATA_CS = (0) +#define SET_CS ILI9325_GPIO1DATA_CS = (1 << ILI9325_CS_PIN) +#define CLR_WR ILI9325_GPIO1DATA_WR = (0) +#define SET_WR ILI9325_GPIO1DATA_WR = (1 << ILI9325_WR_PIN) +#define CLR_RD ILI9325_GPIO1DATA_RD = (0) +#define SET_RD ILI9325_GPIO1DATA_RD = (1 << ILI9325_RD_PIN) +#define CLR_RESET ILI9325_GPIO3DATA_RES = (0) +#define SET_RESET ILI9325_GPIO3DATA_RES = (1 << ILI9325_RES_PIN) + +// These 'combined' macros are defined to improve code performance by +// reducing the number of instructions in heavily used functions +#define CLR_CS_CD ILI9325_GPIO1DATA_CS_CD = (0); +#define SET_RD_WR ILI9325_GPIO1DATA_RD_WR = (ILI9325_RD_WR_PINS); +#define SET_WR_CS ILI9325_GPIO1DATA_WR_CS = (ILI9325_WR_CS_PINS); +#define SET_CD_RD_WR ILI9325_GPIO1DATA_CD_RD_WR = (ILI9325_CD_RD_WR_PINS); +#define CLR_CS_CD_SET_RD_WR ILI9325_GPIO1DATA_CS_CD_RD_WR = (ILI9325_RD_WR_PINS); +#define CLR_CS_SET_CD_RD_WR ILI9325_GPIO1DATA_CS_CD_RD_WR = (ILI9325_CD_RD_WR_PINS); + +enum +{ + ILI9325_COMMANDS_DRIVERCODEREAD = 0x0000, + ILI9325_COMMANDS_DRIVEROUTPUTCONTROL1 = 0x0001, + ILI9325_COMMANDS_LCDDRIVINGCONTROL = 0x0002, + ILI9325_COMMANDS_ENTRYMODE = 0x0003, + ILI9325_COMMANDS_RESIZECONTROL = 0x0004, + ILI9325_COMMANDS_DISPLAYCONTROL1 = 0x0007, + ILI9325_COMMANDS_DISPLAYCONTROL2 = 0x0008, + ILI9325_COMMANDS_DISPLAYCONTROL3 = 0x0009, + ILI9325_COMMANDS_DISPLAYCONTROL4 = 0x000A, + ILI9325_COMMANDS_RGBDISPLAYINTERFACECONTROL1 = 0x000C, + ILI9325_COMMANDS_FRAMEMAKERPOSITION = 0x000D, + ILI9325_COMMANDS_RGBDISPLAYINTERFACECONTROL2 = 0x000F, + ILI9325_COMMANDS_POWERCONTROL1 = 0x0010, + ILI9325_COMMANDS_POWERCONTROL2 = 0x0011, + ILI9325_COMMANDS_POWERCONTROL3 = 0x0012, + ILI9325_COMMANDS_POWERCONTROL4 = 0x0013, + ILI9325_COMMANDS_HORIZONTALGRAMADDRESSSET = 0x0020, + ILI9325_COMMANDS_VERTICALGRAMADDRESSSET = 0x0021, + ILI9325_COMMANDS_WRITEDATATOGRAM = 0x0022, + ILI9325_COMMANDS_POWERCONTROL7 = 0x0029, + ILI9325_COMMANDS_FRAMERATEANDCOLORCONTROL = 0x002B, + ILI9325_COMMANDS_GAMMACONTROL1 = 0x0030, + ILI9325_COMMANDS_GAMMACONTROL2 = 0x0031, + ILI9325_COMMANDS_GAMMACONTROL3 = 0x0032, + ILI9325_COMMANDS_GAMMACONTROL4 = 0x0035, + ILI9325_COMMANDS_GAMMACONTROL5 = 0x0036, + ILI9325_COMMANDS_GAMMACONTROL6 = 0x0037, + ILI9325_COMMANDS_GAMMACONTROL7 = 0x0038, + ILI9325_COMMANDS_GAMMACONTROL8 = 0x0039, + ILI9325_COMMANDS_GAMMACONTROL9 = 0x003C, + ILI9325_COMMANDS_GAMMACONTROL10 = 0x003D, + ILI9325_COMMANDS_HORIZONTALADDRESSSTARTPOSITION = 0x0050, + ILI9325_COMMANDS_HORIZONTALADDRESSENDPOSITION = 0x0051, + ILI9325_COMMANDS_VERTICALADDRESSSTARTPOSITION = 0x0052, + ILI9325_COMMANDS_VERTICALADDRESSENDPOSITION = 0x0053, + ILI9325_COMMANDS_DRIVEROUTPUTCONTROL2 = 0x0060, + ILI9325_COMMANDS_BASEIMAGEDISPLAYCONTROL = 0x0061, + ILI9325_COMMANDS_VERTICALSCROLLCONTROL = 0x006A, + ILI9325_COMMANDS_PARTIALIMAGE1DISPLAYPOSITION = 0x0080, + ILI9325_COMMANDS_PARTIALIMAGE1AREASTARTLINE = 0x0081, + ILI9325_COMMANDS_PARTIALIMAGE1AREAENDLINE = 0x0082, + ILI9325_COMMANDS_PARTIALIMAGE2DISPLAYPOSITION = 0x0083, + ILI9325_COMMANDS_PARTIALIMAGE2AREASTARTLINE = 0x0084, + ILI9325_COMMANDS_PARTIALIMAGE2AREAENDLINE = 0x0085, + ILI9325_COMMANDS_PANELINTERFACECONTROL1 = 0x0090, + ILI9325_COMMANDS_PANELINTERFACECONTROL2 = 0x0092, + ILI9325_COMMANDS_PANELINTERFACECONTROL4 = 0x0095, + ILI9325_COMMANDS_OTPVCMPROGRAMMINGCONTROL = 0x00A1, + ILI9325_COMMANDS_OTPVCMSTATUSANDENABLE = 0x00A2, + ILI9325_COMMANDS_OTPPROGRAMMINGIDKEY = 0x00A5 +}; + +#endif diff --git a/drivers/lcd/tft/hw/ILI9328.c b/drivers/lcd/tft/hw/ILI9328.c new file mode 100644 index 0000000..b7a69eb --- /dev/null +++ b/drivers/lcd/tft/hw/ILI9328.c @@ -0,0 +1,616 @@ +/**************************************************************************/ +/*! + @file ILI9328.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for ILI9328 240x320 pixel TFT LCD displays. + + This driver uses an 8-bit interface and a 16-bit RGB565 colour palette. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "ILI9328.h" +#include "core/systick/systick.h" +#include "drivers/lcd/tft/touchscreen.h" + +static volatile lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT; +static lcdProperties_t ili9328Properties = { 240, 320, TRUE, TRUE, TRUE }; + +/*************************************************/ +/* Private Methods */ +/*************************************************/ + +/**************************************************************************/ +/*! + @brief Causes a brief delay (10 ticks per unit) +*/ +/**************************************************************************/ +void ili9328Delay(unsigned int t) +{ + unsigned char t1; + while(t--) + for ( t1=10; t1 > 0; t1-- ) + { + __asm("nop"); + } +} + +/**************************************************************************/ +/*! + @brief Writes the supplied 16-bit command using an 8-bit interface +*/ +/**************************************************************************/ +void ili9328WriteCmd(uint16_t command) +{ + // Compiled with -Os on GCC 4.4 this works out to 25 cycles + // (versus 36 compiled with no optimisations). I'm not sure it + // can be improved further, so that means 25 cycles/350nS for + // continuous writes (cmd, data, data, data, ...) or ~150 cycles/ + // ~2.1uS for a random pixel (Set X [cmd+data], Set Y [cmd+data], + // Set color [cmd+data]) (times assumes 72MHz clock). + + CLR_CS_CD_SET_RD_WR; // Saves 18 commands compared to "CLR_CS; CLR_CD; SET_RD; SET_WR;" + ILI9328_GPIO2DATA_DATA = (command >> (8 - ILI9328_DATA_OFFSET)); + CLR_WR; + SET_WR; + ILI9328_GPIO2DATA_DATA = command << ILI9328_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR; SET_CS;" +} + +/**************************************************************************/ +/*! + @brief Writes the supplied 16-bit data using an 8-bit interface +*/ +/**************************************************************************/ +void ili9328WriteData(uint16_t data) +{ + CLR_CS_SET_CD_RD_WR; // Saves 18 commands compared to SET_CD; SET_RD; SET_WR; CLR_CS" + ILI9328_GPIO2DATA_DATA = (data >> (8 - ILI9328_DATA_OFFSET)); + CLR_WR; + SET_WR; + ILI9328_GPIO2DATA_DATA = data << ILI9328_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR, SET_CS;" +} + +/**************************************************************************/ +/*! + @brief Reads a 16-bit value from the 8-bit data bus +*/ +/**************************************************************************/ +uint16_t ili9328ReadData(void) +{ + // ToDo: Optimise this method! + + uint16_t high, low; + high = low = 0; + uint16_t d; + + SET_CD_RD_WR; // Saves 14 commands compared to "SET_CD; SET_RD; SET_WR" + CLR_CS; + + // set inputs + ILI9328_GPIO2DATA_SETINPUT; + CLR_RD; + ili9328Delay(100); + high = ILI9328_GPIO2DATA_DATA; + high >>= ILI9328_DATA_OFFSET; + high &= 0xFF; + SET_RD; + + CLR_RD; + ili9328Delay(100); + low = ILI9328_GPIO2DATA_DATA; + low >>= ILI9328_DATA_OFFSET; + low &=0xFF; + SET_RD; + + SET_CS; + ILI9328_GPIO2DATA_SETOUTPUT; + + d = high; + d <<= 8; + d |= low; + + return d; +} + +/**************************************************************************/ +/*! + @brief Reads a 16-bit value +*/ +/**************************************************************************/ +uint16_t ili9328Read(uint16_t addr) +{ + ili9328WriteCmd(addr); + return ili9328ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sends a 16-bit command + 16-bit data +*/ +/**************************************************************************/ +void ili9328Command(uint16_t command, uint16_t data) +{ + ili9328WriteCmd(command); + ili9328WriteData(data); +} + +/**************************************************************************/ +/*! + @brief Returns the 16-bit (4-hexdigit) controller code +*/ +/**************************************************************************/ +uint16_t ili9328Type(void) +{ + ili9328WriteCmd(ILI9328_COMMANDS_DRIVERCODEREAD); + return ili9328ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sets the cursor to the specified X/Y position +*/ +/**************************************************************************/ +void ili9328SetCursor(uint16_t x, uint16_t y) +{ + uint16_t al, ah; + + if (lcdOrientation == LCD_ORIENTATION_LANDSCAPE) + { + al = y; + ah = x; + } + else + { + al = x; + ah = y; + } + + ili9328Command(ILI9328_COMMANDS_HORIZONTALGRAMADDRESSSET, al); + ili9328Command(ILI9328_COMMANDS_VERTICALGRAMADDRESSSET, ah); +} + +/**************************************************************************/ +/*! + @brief Sends the initialisation sequence to the display controller +*/ +/**************************************************************************/ +void ili9328InitDisplay(void) +{ + // Clear data line + GPIO_GPIO2DATA &= ~ILI9328_DATA_MASK; + + SET_RD; + SET_WR; + SET_CS; + SET_CD; + + // Reset display + CLR_RESET; + ili9328Delay(100); + SET_RESET; + ili9328Delay(1000); + + ili9328Command(ILI9328_COMMANDS_DRIVEROUTPUTCONTROL1, 0x0100); // Driver Output Control Register (R01h) + ili9328Command(ILI9328_COMMANDS_LCDDRIVINGCONTROL, 0x0700); // LCD Driving Waveform Control (R02h) + ili9328Command(ILI9328_COMMANDS_ENTRYMODE, 0x1030); // Entry Mode (R03h) + ili9328Command(ILI9328_COMMANDS_DISPLAYCONTROL2, 0x0302); + ili9328Command(ILI9328_COMMANDS_DISPLAYCONTROL3, 0x0000); + ili9328Command(ILI9328_COMMANDS_DISPLAYCONTROL4, 0x0000); // Fmark On + ili9328Command(ILI9328_COMMANDS_POWERCONTROL1, 0x0000); // Power Control 1 (R10h) + ili9328Command(ILI9328_COMMANDS_POWERCONTROL2, 0x0007); // Power Control 2 (R11h) + ili9328Command(ILI9328_COMMANDS_POWERCONTROL3, 0x0000); // Power Control 3 (R12h) + ili9328Command(ILI9328_COMMANDS_POWERCONTROL4, 0x0000); // Power Control 4 (R13h) + ili9328Delay(1000); + ili9328Command(ILI9328_COMMANDS_POWERCONTROL1, 0x14B0); // Power Control 1 (R10h) + ili9328Delay(500); + ili9328Command(ILI9328_COMMANDS_POWERCONTROL2, 0x0007); // Power Control 2 (R11h) + ili9328Delay(500); + ili9328Command(ILI9328_COMMANDS_POWERCONTROL3, 0x008E); // Power Control 3 (R12h) + ili9328Command(ILI9328_COMMANDS_POWERCONTROL4, 0x0C00); // Power Control 4 (R13h) + ili9328Command(ILI9328_COMMANDS_POWERCONTROL7, 0x0015); // NVM read data 2 (R29h) + ili9328Delay(500); + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL1, 0x0000); // Gamma Control 1 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL2, 0x0107); // Gamma Control 2 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL3, 0x0000); // Gamma Control 3 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL4, 0x0203); // Gamma Control 4 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL5, 0x0402); // Gamma Control 5 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL6, 0x0000); // Gamma Control 6 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL7, 0x0207); // Gamma Control 7 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL8, 0x0000); // Gamma Control 8 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL9, 0x0203); // Gamma Control 9 + ili9328Command(ILI9328_COMMANDS_GAMMACONTROL10, 0x0403); // Gamma Control 10 + ili9328Command(ILI9328_COMMANDS_HORIZONTALADDRESSSTARTPOSITION, 0x0000); // Window Horizontal RAM Address Start (R50h) + ili9328Command(ILI9328_COMMANDS_HORIZONTALADDRESSENDPOSITION, ili9328Properties.width - 1); // Window Horizontal RAM Address End (R51h) + ili9328Command(ILI9328_COMMANDS_VERTICALADDRESSSTARTPOSITION, 0X0000); // Window Vertical RAM Address Start (R52h) + ili9328Command(ILI9328_COMMANDS_VERTICALADDRESSENDPOSITION, ili9328Properties.height - 1); // Window Vertical RAM Address End (R53h) + ili9328Command(ILI9328_COMMANDS_DRIVEROUTPUTCONTROL2, 0xa700); // Driver Output Control (R60h) + ili9328Command(ILI9328_COMMANDS_BASEIMAGEDISPLAYCONTROL, 0x0003); // Driver Output Control (R61h) - enable VLE + ili9328Command(ILI9328_COMMANDS_PANELINTERFACECONTROL1, 0X0010); // Panel Interface Control 1 (R90h) + + // Display On + ili9328Command(ILI9328_COMMANDS_DISPLAYCONTROL1, 0x0133); // Display Control (R07h) + ili9328Delay(500); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); +} + +/**************************************************************************/ +/*! + @brief Sets the cursor to the home position (0,0) +*/ +/**************************************************************************/ +void ili9328Home(void) +{ + ili9328SetCursor(0, 0); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) +} + +/**************************************************************************/ +/*! + @brief Sets the window confines +*/ +/**************************************************************************/ +void ili9328SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + ili9328Command(ILI9328_COMMANDS_HORIZONTALADDRESSSTARTPOSITION, x0); + ili9328Command(ILI9328_COMMANDS_HORIZONTALADDRESSENDPOSITION, x1); + ili9328Command(ILI9328_COMMANDS_VERTICALADDRESSSTARTPOSITION, y0); + ili9328Command(ILI9328_COMMANDS_VERTICALADDRESSENDPOSITION, y1); + ili9328SetCursor(x0, y0); +} + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +/**************************************************************************/ +/*! + @brief Configures any pins or HW and initialises the LCD controller +*/ +/**************************************************************************/ +void lcdInit(void) +{ + // Set control line pins to output + gpioSetDir(ILI9328_CS_PORT, ILI9328_CS_PIN, 1); + gpioSetDir(ILI9328_CD_PORT, ILI9328_CD_PIN, 1); + gpioSetDir(ILI9328_WR_PORT, ILI9328_WR_PIN, 1); + gpioSetDir(ILI9328_RD_PORT, ILI9328_RD_PIN, 1); + + // Set data port pins to output + ILI9328_GPIO2DATA_SETOUTPUT; + + // Disable pullups + ILI9328_DISABLEPULLUPS(); + + // Set backlight pin to output and turn it on + gpioSetDir(ILI9328_BL_PORT, ILI9328_BL_PIN, 1); // set to output + lcdBacklight(TRUE); + + // Set reset pin to output + gpioSetDir(ILI9328_RES_PORT, ILI9328_RES_PIN, 1); // Set to output + gpioSetValue(ILI9328_RES_PORT, ILI9328_RES_PIN, 0); // Low to reset + systickDelay(50); + gpioSetValue(ILI9328_RES_PORT, ILI9328_RES_PIN, 1); // High to exit + + // Initialize the display + ili9328InitDisplay(); + + systickDelay(50); + + // Set lcd to default orientation + lcdSetOrientation(lcdOrientation); + + // Fill black + lcdFillRGB(COLOR_BLACK); + + // Initialise the touch screen (and calibrate if necessary) + tsInit(); +} + +/**************************************************************************/ +/*! + @brief Enables or disables the LCD backlight +*/ +/**************************************************************************/ +void lcdBacklight(bool state) +{ + // Set the backlight + gpioSetValue(ILI9328_BL_PORT, ILI9328_BL_PIN, state ? 0 : 1); +} + +/**************************************************************************/ +/*! + @brief Renders a simple test pattern on the LCD +*/ +/**************************************************************************/ +void lcdTest(void) +{ + uint32_t i,j; + ili9328Home(); + + for(i=0;i<320;i++) + { + for(j=0;j<240;j++) + { + if(i>279)ili9328WriteData(COLOR_WHITE); + else if(i>239)ili9328WriteData(COLOR_BLUE); + else if(i>199)ili9328WriteData(COLOR_GREEN); + else if(i>159)ili9328WriteData(COLOR_CYAN); + else if(i>119)ili9328WriteData(COLOR_RED); + else if(i>79)ili9328WriteData(COLOR_MAGENTA); + else if(i>39)ili9328WriteData(COLOR_YELLOW); + else ili9328WriteData(COLOR_BLACK); + } + } +} + +/**************************************************************************/ +/*! + @brief Fills the LCD with the specified 16-bit color +*/ +/**************************************************************************/ +void lcdFillRGB(uint16_t data) +{ + unsigned int i; + ili9328Home(); + + uint32_t pixels = 320*240; + for ( i=0; i < pixels; i++ ) + { + ili9328WriteData(data); + } +} + +/**************************************************************************/ +/*! + @brief Draws a single pixel at the specified X/Y location +*/ +/**************************************************************************/ +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + ili9328SetCursor(x, y); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) + ili9328WriteData(color); +} + +/**************************************************************************/ +/*! + @brief Draws an array of consecutive RGB565 pixels (much + faster than addressing each pixel individually) +*/ +/**************************************************************************/ +void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len) +{ + uint32_t i = 0; + ili9328SetCursor(x, y); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); + do + { + ili9328WriteData(data[i]); + i++; + } while (i= lcdGetWidth()) + { + x1 = lcdGetWidth() - 1; + } + if (x0 >= lcdGetWidth()) + { + x0 = lcdGetWidth() - 1; + } + + ili9328SetCursor(x0, y); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); // Write Data to GRAM (R22h) + for (pixels = 0; pixels < x1 - x0 + 1; pixels++) + { + ili9328WriteData(color); + } +} + +/**************************************************************************/ +/*! + @brief Optimised routine to draw a vertical line faster than + setting individual pixels +*/ +/**************************************************************************/ +void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color) +{ + lcdOrientation_t orientation = lcdOrientation; + + // Switch orientation + lcdSetOrientation(orientation == LCD_ORIENTATION_PORTRAIT ? LCD_ORIENTATION_LANDSCAPE : LCD_ORIENTATION_PORTRAIT); + + // Draw horizontal line like usual + lcdDrawHLine(y0, y1, lcdGetHeight() - (x + 1), color); + + // Switch orientation back + lcdSetOrientation(orientation); +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit color of the pixel at the specified location +*/ +/**************************************************************************/ +uint16_t lcdGetPixel(uint16_t x, uint16_t y) +{ + uint16_t preFetch = 0; + + ili9328SetCursor(x, y); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); + preFetch = ili9328ReadData(); + + // Eeek ... why does this need to be done twice for a proper value?!? + ili9328SetCursor(x, y); + ili9328WriteCmd(ILI9328_COMMANDS_WRITEDATATOGRAM); + return ili9328ReadData(); +} + +/**************************************************************************/ +/*! + @brief Sets the LCD orientation to horizontal and vertical +*/ +/**************************************************************************/ +void lcdSetOrientation(lcdOrientation_t orientation) +{ + uint16_t entryMode = 0x1030; + uint16_t outputControl = 0x0100; + + switch (orientation) + { + case LCD_ORIENTATION_PORTRAIT: + entryMode = 0x1030; + outputControl = 0x0100; + break; + case LCD_ORIENTATION_LANDSCAPE: + entryMode = 0x1028; + outputControl = 0x0000; + break; + } + + ili9328Command(ILI9328_COMMANDS_ENTRYMODE, entryMode); + ili9328Command(ILI9328_COMMANDS_DRIVEROUTPUTCONTROL1, outputControl); + lcdOrientation = orientation; + + ili9328SetCursor(0, 0); +} + +/**************************************************************************/ +/*! + @brief Gets the current screen orientation (horizontal or vertical) +*/ +/**************************************************************************/ +lcdOrientation_t lcdGetOrientation(void) +{ + return lcdOrientation; +} + +/**************************************************************************/ +/*! + @brief Gets the width in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetWidth(void) +{ + switch (lcdOrientation) + { + case LCD_ORIENTATION_PORTRAIT: + return ili9328Properties.width; + break; + case LCD_ORIENTATION_LANDSCAPE: + default: + return ili9328Properties.height; + } +} + +/**************************************************************************/ +/*! + @brief Gets the height in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetHeight(void) +{ + switch (lcdOrientation) + { + case LCD_ORIENTATION_PORTRAIT: + return ili9328Properties.height; + break; + case LCD_ORIENTATION_LANDSCAPE: + default: + return ili9328Properties.width; + } +} + +/**************************************************************************/ +/*! + @brief Scrolls the contents of the LCD screen vertically the + specified number of pixels using a HW optimised routine +*/ +/**************************************************************************/ +void lcdScroll(int16_t pixels, uint16_t fillColor) +{ + int16_t y = pixels; + while (y < 0) + y += 320; + while (y >= 320) + y -= 320; + ili9328WriteCmd(ILI9328_COMMANDS_VERTICALSCROLLCONTROL); + ili9328WriteData(y); +} + +/**************************************************************************/ +/*! + @brief Gets the controller's 16-bit (4 hexdigit) ID +*/ +/**************************************************************************/ +uint16_t lcdGetControllerID(void) +{ + return ili9328Type(); +} + +/**************************************************************************/ +/*! + @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs + generic capabilities and dimensions +*/ +/**************************************************************************/ +lcdProperties_t lcdGetProperties(void) +{ + return ili9328Properties; +} diff --git a/drivers/lcd/tft/hw/ILI9328.h b/drivers/lcd/tft/hw/ILI9328.h new file mode 100644 index 0000000..82cedb6 --- /dev/null +++ b/drivers/lcd/tft/hw/ILI9328.h @@ -0,0 +1,185 @@ +/**************************************************************************/ +/*! + @file ILI9328.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __ILI9328_H__ +#define __ILI9328_H__ + +#include "projectconfig.h" + +#include "drivers/lcd/tft/lcd.h" +#include "core/gpio/gpio.h" + +// Control pins +#define ILI9328_CS_PORT 1 // CS (LCD Pin 7) +#define ILI9328_CS_PIN 8 +#define ILI9328_CD_PORT 1 // CS/RS (LCD Pin 8) +#define ILI9328_CD_PIN 9 +#define ILI9328_WR_PORT 1 // WR (LCD Pin 9) +#define ILI9328_WR_PIN 10 +#define ILI9328_RD_PORT 1 // RD (LCD Pin 10) +#define ILI9328_RD_PIN 11 + +// These combined pin definitions are for optimisation purposes. +// If the pin values above are modified the bit equivalents +// below will also need to be updated +#define ILI9328_CS_CD_PINS 0x300 // 8 + 9 +#define ILI9328_RD_WR_PINS 0xC00 // 11 + 10 +#define ILI9328_WR_CS_PINS 0x500 // 10 + 8 +#define ILI9328_CD_RD_WR_PINS 0xE00 // 9 + 11 + 10 +#define ILI9328_CS_CD_RD_WR_PINS 0xF00 // 8 + 9 + 11 + 10 + +// Backlight and Reset pins +#define ILI9328_RES_PORT 3 // LCD Reset (LCD Pin 31) +#define ILI9328_RES_PIN 3 +#define ILI9328_BL_PORT 2 // Backlight Enable (LCD Pin 16) +#define ILI9328_BL_PIN 9 + +// Data pins +// Note: data pins must be consecutive and on the same port +#define ILI9328_DATA_PORT 2 // 8-Pin Data Port +#define ILI9328_DATA_PIN1 1 +#define ILI9328_DATA_PIN2 2 +#define ILI9328_DATA_PIN3 3 +#define ILI9328_DATA_PIN4 4 +#define ILI9328_DATA_PIN5 5 +#define ILI9328_DATA_PIN6 6 +#define ILI9328_DATA_PIN7 7 +#define ILI9328_DATA_PIN8 8 +#define ILI9328_DATA_MASK 0x000001FE +#define ILI9328_DATA_OFFSET 1 // Offset = PIN1 + +// Placed here to try to keep all pin specific values in header file +#define ILI9328_DISABLEPULLUPS() do { gpioSetPullup(&IOCON_PIO2_1, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_2, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_3, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_4, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_5, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_6, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_7, gpioPullupMode_Inactive); \ + gpioSetPullup(&IOCON_PIO2_8, gpioPullupMode_Inactive); } while (0) + +// These registers allow fast single operation clear+set of bits (see section 8.5.1 of LPC1343 UM) +#define ILI9328_GPIO2DATA_DATA (*(pREG32 (GPIO_GPIO2_BASE + (ILI9328_DATA_MASK << 2)))) +#define ILI9328_GPIO1DATA_WR (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9328_WR_PIN) << 2)))) +#define ILI9328_GPIO1DATA_CD (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9328_CD_PIN) << 2)))) +#define ILI9328_GPIO1DATA_CS (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9328_CS_PIN) << 2)))) +#define ILI9328_GPIO1DATA_RD (*(pREG32 (GPIO_GPIO1_BASE + ((1 << ILI9328_RD_PIN) << 2)))) +#define ILI9328_GPIO3DATA_RES (*(pREG32 (GPIO_GPIO3_BASE + ((1 << ILI9328_RES_PIN) << 2)))) +#define ILI9328_GPIO1DATA_CS_CD (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9328_CS_CD_PINS) << 2)))) +#define ILI9328_GPIO1DATA_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9328_RD_WR_PINS) << 2)))) +#define ILI9328_GPIO1DATA_WR_CS (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9328_WR_CS_PINS) << 2)))) +#define ILI9328_GPIO1DATA_CD_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9328_CD_RD_WR_PINS) << 2)))) +#define ILI9328_GPIO1DATA_CS_CD_RD_WR (*(pREG32 (GPIO_GPIO1_BASE + ((ILI9328_CS_CD_RD_WR_PINS) << 2)))) + +// Macros to set data bus direction to input/output +#define ILI9328_GPIO2DATA_SETINPUT GPIO_GPIO2DIR &= ~ILI9328_DATA_MASK +#define ILI9328_GPIO2DATA_SETOUTPUT GPIO_GPIO2DIR |= ILI9328_DATA_MASK + +// Macros for control line state +#define CLR_CD ILI9328_GPIO1DATA_CD = (0) +#define SET_CD ILI9328_GPIO1DATA_CD = (1 << ILI9328_CD_PIN) +#define CLR_CS ILI9328_GPIO1DATA_CS = (0) +#define SET_CS ILI9328_GPIO1DATA_CS = (1 << ILI9328_CS_PIN) +#define CLR_WR ILI9328_GPIO1DATA_WR = (0) +#define SET_WR ILI9328_GPIO1DATA_WR = (1 << ILI9328_WR_PIN) +#define CLR_RD ILI9328_GPIO1DATA_RD = (0) +#define SET_RD ILI9328_GPIO1DATA_RD = (1 << ILI9328_RD_PIN) +#define CLR_RESET ILI9328_GPIO3DATA_RES = (0) +#define SET_RESET ILI9328_GPIO3DATA_RES = (1 << ILI9328_RES_PIN) + +// These 'combined' macros are defined to improve code performance by +// reducing the number of instructions in heavily used functions +#define CLR_CS_CD ILI9328_GPIO1DATA_CS_CD = (0); +#define SET_RD_WR ILI9328_GPIO1DATA_RD_WR = (ILI9328_RD_WR_PINS); +#define SET_WR_CS ILI9328_GPIO1DATA_WR_CS = (ILI9328_WR_CS_PINS); +#define SET_CD_RD_WR ILI9328_GPIO1DATA_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); +#define CLR_CS_CD_SET_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_RD_WR_PINS); +#define CLR_CS_SET_CD_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); + +enum +{ + ILI9328_COMMANDS_DRIVERCODEREAD = 0x0000, + ILI9328_COMMANDS_DRIVEROUTPUTCONTROL1 = 0x0001, + ILI9328_COMMANDS_LCDDRIVINGCONTROL = 0x0002, + ILI9328_COMMANDS_ENTRYMODE = 0x0003, + ILI9328_COMMANDS_RESIZECONTROL = 0x0004, + ILI9328_COMMANDS_DISPLAYCONTROL1 = 0x0007, + ILI9328_COMMANDS_DISPLAYCONTROL2 = 0x0008, + ILI9328_COMMANDS_DISPLAYCONTROL3 = 0x0009, + ILI9328_COMMANDS_DISPLAYCONTROL4 = 0x000A, + ILI9328_COMMANDS_RGBDISPLAYINTERFACECONTROL1 = 0x000C, + ILI9328_COMMANDS_FRAMEMAKERPOSITION = 0x000D, + ILI9328_COMMANDS_RGBDISPLAYINTERFACECONTROL2 = 0x000F, + ILI9328_COMMANDS_POWERCONTROL1 = 0x0010, + ILI9328_COMMANDS_POWERCONTROL2 = 0x0011, + ILI9328_COMMANDS_POWERCONTROL3 = 0x0012, + ILI9328_COMMANDS_POWERCONTROL4 = 0x0013, + ILI9328_COMMANDS_HORIZONTALGRAMADDRESSSET = 0x0020, + ILI9328_COMMANDS_VERTICALGRAMADDRESSSET = 0x0021, + ILI9328_COMMANDS_WRITEDATATOGRAM = 0x0022, + ILI9328_COMMANDS_POWERCONTROL7 = 0x0029, + ILI9328_COMMANDS_FRAMERATEANDCOLORCONTROL = 0x002B, + ILI9328_COMMANDS_GAMMACONTROL1 = 0x0030, + ILI9328_COMMANDS_GAMMACONTROL2 = 0x0031, + ILI9328_COMMANDS_GAMMACONTROL3 = 0x0032, + ILI9328_COMMANDS_GAMMACONTROL4 = 0x0035, + ILI9328_COMMANDS_GAMMACONTROL5 = 0x0036, + ILI9328_COMMANDS_GAMMACONTROL6 = 0x0037, + ILI9328_COMMANDS_GAMMACONTROL7 = 0x0038, + ILI9328_COMMANDS_GAMMACONTROL8 = 0x0039, + ILI9328_COMMANDS_GAMMACONTROL9 = 0x003C, + ILI9328_COMMANDS_GAMMACONTROL10 = 0x003D, + ILI9328_COMMANDS_HORIZONTALADDRESSSTARTPOSITION = 0x0050, + ILI9328_COMMANDS_HORIZONTALADDRESSENDPOSITION = 0x0051, + ILI9328_COMMANDS_VERTICALADDRESSSTARTPOSITION = 0x0052, + ILI9328_COMMANDS_VERTICALADDRESSENDPOSITION = 0x0053, + ILI9328_COMMANDS_DRIVEROUTPUTCONTROL2 = 0x0060, + ILI9328_COMMANDS_BASEIMAGEDISPLAYCONTROL = 0x0061, + ILI9328_COMMANDS_VERTICALSCROLLCONTROL = 0x006A, + ILI9328_COMMANDS_PARTIALIMAGE1DISPLAYPOSITION = 0x0080, + ILI9328_COMMANDS_PARTIALIMAGE1AREASTARTLINE = 0x0081, + ILI9328_COMMANDS_PARTIALIMAGE1AREAENDLINE = 0x0082, + ILI9328_COMMANDS_PARTIALIMAGE2DISPLAYPOSITION = 0x0083, + ILI9328_COMMANDS_PARTIALIMAGE2AREASTARTLINE = 0x0084, + ILI9328_COMMANDS_PARTIALIMAGE2AREAENDLINE = 0x0085, + ILI9328_COMMANDS_PANELINTERFACECONTROL1 = 0x0090, + ILI9328_COMMANDS_PANELINTERFACECONTROL2 = 0x0092, + ILI9328_COMMANDS_PANELINTERFACECONTROL4 = 0x0095, + ILI9328_COMMANDS_OTPVCMPROGRAMMINGCONTROL = 0x00A1, + ILI9328_COMMANDS_OTPVCMSTATUSANDENABLE = 0x00A2, + ILI9328_COMMANDS_OTPPROGRAMMINGIDKEY = 0x00A5 +}; + +#endif diff --git a/drivers/lcd/tft/hw/readme.txt b/drivers/lcd/tft/hw/readme.txt new file mode 100644 index 0000000..dd0ec4c --- /dev/null +++ b/drivers/lcd/tft/hw/readme.txt @@ -0,0 +1,12 @@ +HW-Specific LCD Drivers +======================= + +ILI9325 - 240x320 16-bit display (8-bit interface) +ILI9328 - 240x320 16-bit display (8-bit interface) +st7735 - 128x160 16-bit display (Bit-banged SPI interface) +st7783 - 240x320 16-bit displays (8-bit interface) + +NOTE: Only the ILI9325 and ILI9328 drivers have been fully tested. +The others are incomplete or have only been partially tested. (The +ST7783 driver, for example, has issues when the screen orientation +is set to landscape.) \ No newline at end of file diff --git a/drivers/lcd/tft/hw/st7735.c b/drivers/lcd/tft/hw/st7735.c new file mode 100644 index 0000000..939015e --- /dev/null +++ b/drivers/lcd/tft/hw/st7735.c @@ -0,0 +1,444 @@ +/**************************************************************************/ +/*! + @file st7735.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for st7735 128x160 pixel TFT LCD displays. + + This driver uses a bit-banged SPI interface and a 16-bit RGB565 + colour palette. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "st7735.h" +#include "core/systick/systick.h" +#include "core/gpio/gpio.h" + +static lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT; +static lcdProperties_t st7735Properties = { 128, 160, FALSE, FALSE, FALSE }; + +/*************************************************/ +/* Private Methods */ +/*************************************************/ + +/*************************************************/ +void st7735WriteCmd(uint8_t command) +{ + CLR_CS; + CLR_RS; + uint8_t i = 0; + for (i=0; i<8; i++) + { + if (command & 0x80) + { + SET_SDA; + } + else + { + CLR_SDA; + } + CLR_SCL; + command <<= 1; + SET_SCL; + } + SET_CS; +} + +/*************************************************/ +void st7735WriteData(uint8_t data) +{ + CLR_CS; + SET_RS; + uint8_t i = 0; + for (i=0; i<8; i++) + { + if (data & 0x80) + { + SET_SDA; + } + else + { + CLR_SDA; + } + CLR_SCL; + data <<= 1; + SET_SCL; + } + SET_CS; +} + +/*************************************************/ +void st7735SetAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) +{ + st7735WriteCmd(ST7735_CASET); // column addr set + st7735WriteData(0x00); + st7735WriteData(x0+2); // XSTART + st7735WriteData(0x00); + st7735WriteData(x1+2); // XEND + + st7735WriteCmd(ST7735_RASET); // row addr set + st7735WriteData(0x00); + st7735WriteData(y0+1); // YSTART + st7735WriteData(0x00); + st7735WriteData(y1+1); // YEND +} + +/*************************************************/ +void st7735InitDisplay(void) +{ + st7735WriteCmd(ST7735_SWRESET); // software reset + systickDelay(50); + st7735WriteCmd(ST7735_SLPOUT); // out of sleep mode + systickDelay(500); + + st7735WriteCmd(ST7735_COLMOD); // set color mode + st7735WriteData(0x05); // 16-bit color + systickDelay(10); + + st7735WriteCmd(ST7735_FRMCTR1); // frame rate control + st7735WriteData(0x00); // fastest refresh + st7735WriteData(0x06); // 6 lines front porch + st7735WriteData(0x03); // 3 lines backporch + systickDelay(10); + + st7735WriteCmd(ST7735_MADCTL); // memory access control (directions) + st7735WriteData(0xC8); // row address/col address, bottom to top refresh + + st7735WriteCmd(ST7735_DISSET5); // display settings #5 + st7735WriteData(0x15); // 1 clock cycle nonoverlap, 2 cycle gate rise, 3 cycle oscil. equalize + st7735WriteData(0x02); // fix on VTL + + st7735WriteCmd(ST7735_INVCTR); // display inversion control + st7735WriteData(0x0); // line inversion + + st7735WriteCmd(ST7735_PWCTR1); // power control + st7735WriteData(0x02); // GVDD = 4.7V + st7735WriteData(0x70); // 1.0uA + systickDelay(10); + st7735WriteCmd(ST7735_PWCTR2); // power control + st7735WriteData(0x05); // VGH = 14.7V, VGL = -7.35V + st7735WriteCmd(ST7735_PWCTR3); // power control + st7735WriteData(0x01); // Opamp current small + st7735WriteData(0x02); // Boost frequency + + + st7735WriteCmd(ST7735_VMCTR1); // power control + st7735WriteData(0x3C); // VCOMH = 4V + st7735WriteData(0x38); // VCOML = -1.1V + systickDelay(10); + + st7735WriteCmd(ST7735_PWCTR6); // power control + st7735WriteData(0x11); + st7735WriteData(0x15); + + st7735WriteCmd(ST7735_GMCTRP1); + st7735WriteData(0x09); + st7735WriteData(0x16); + st7735WriteData(0x09); + st7735WriteData(0x20); + st7735WriteData(0x21); + st7735WriteData(0x1B); + st7735WriteData(0x13); + st7735WriteData(0x19); + st7735WriteData(0x17); + st7735WriteData(0x15); + st7735WriteData(0x1E); + st7735WriteData(0x2B); + st7735WriteData(0x04); + st7735WriteData(0x05); + st7735WriteData(0x02); + st7735WriteData(0x0E); + st7735WriteCmd(ST7735_GMCTRN1); + st7735WriteData(0x0B); + st7735WriteData(0x14); + st7735WriteData(0x08); + st7735WriteData(0x1E); + st7735WriteData(0x22); + st7735WriteData(0x1D); + st7735WriteData(0x18); + st7735WriteData(0x1E); + st7735WriteData(0x1B); + st7735WriteData(0x1A); + st7735WriteData(0x24); + st7735WriteData(0x2B); + st7735WriteData(0x06); + st7735WriteData(0x06); + st7735WriteData(0x02); + st7735WriteData(0x0F); + systickDelay(10); + + st7735WriteCmd(ST7735_CASET); // column addr set + st7735WriteData(0x00); + st7735WriteData(0x02); // XSTART = 2 + st7735WriteData(0x00); + st7735WriteData(0x81); // XEND = 129 + + st7735WriteCmd(ST7735_RASET); // row addr set + st7735WriteData(0x00); + st7735WriteData(0x02); // XSTART = 1 + st7735WriteData(0x00); + st7735WriteData(0x81); // XEND = 160 + + st7735WriteCmd(ST7735_NORON); // normal display on + systickDelay(10); + + st7735WriteCmd(ST7735_DISPON); + systickDelay(500); +} + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +/*************************************************/ +void lcdInit(void) +{ + // Set control pins to output + gpioSetDir(ST7735_PORT, ST7735_RS_PIN, 1); + gpioSetDir(ST7735_PORT, ST7735_SDA_PIN, 1); + gpioSetDir(ST7735_PORT, ST7735_SCL_PIN, 1); + gpioSetDir(ST7735_PORT, ST7735_CS_PIN, 1); + gpioSetDir(ST7735_PORT, ST7735_RES_PIN, 1); + gpioSetDir(ST7735_PORT, ST7735_BL_PIN, 1); + + // Set pins low by default (except reset) + CLR_RS; + CLR_SDA; + CLR_SCL; + CLR_CS; + CLR_BL; + SET_RES; + + // Turn backlight on + lcdBacklight(TRUE); + + // Reset display + SET_RES; + systickDelay(50); + CLR_RES; + systickDelay(50); + SET_RES; + systickDelay(50); + + // Run LCD init sequence + st7735InitDisplay(); + + // Fill black + lcdFillRGB(COLOR_BLACK); +} + +/*************************************************/ +void lcdBacklight(bool state) +{ + // Set the backlight + // Note: Depending on the type of transistor used + // to control the backlight, you made need to invert + // the values below + if (state) + // CLR_BL; + SET_BL; + else + // SET_BL; + CLR_BL; +} + +/*************************************************/ +void lcdTest(void) +{ + uint8_t i = 0; + for (i = 0; i < 100; i++) + { + lcdDrawPixel(i, i, 0xFFFF); + } +} + +/*************************************************/ +void lcdFillRGB(uint16_t color) +{ + uint8_t x, y; + st7735SetAddrWindow(0, 0, lcdGetWidth() - 1, lcdGetHeight() - 1); + st7735WriteCmd(ST7735_RAMWR); // write to RAM + for (x=0; x < lcdGetWidth(); x++) + { + for (y=0; y < lcdGetHeight(); y++) + { + st7735WriteData(color >> 8); + st7735WriteData(color); + } + } + st7735WriteCmd(ST7735_NOP); +} + +/*************************************************/ +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + st7735SetAddrWindow(x,y,x+1,y+1); + st7735WriteCmd(ST7735_RAMWR); // write to RAM + st7735WriteData(color >> 8); + st7735WriteData(color); +} + +/**************************************************************************/ +/*! + @brief Draws an array of consecutive RGB565 pixels (much + faster than addressing each pixel individually) +*/ +/**************************************************************************/ +void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len) +{ + // ToDo: Optimise this function ... currently only a placeholder + uint32_t i = 0; + do + { + lcdDrawPixel(x+i, y, data[i]); + i++; + } while (i= lcdGetWidth()) + { + x1 = lcdGetWidth() - 1; + } + if (x0 >= lcdGetWidth()) + { + x0 = lcdGetWidth() - 1; + } + + st7735SetAddrWindow(x0, y, lcdGetWidth(), y + 1); + st7735WriteCmd(ST7735_RAMWR); // write to RAM + for (pixels = 0; pixels < x1 - x0 + 1; pixels++) + { + st7735WriteData(color >> 8); + st7735WriteData(color); + } + st7735WriteCmd(ST7735_NOP); +} + +/*************************************************/ +void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color) +{ + // Allows for slightly better performance than setting individual pixels + uint16_t y, pixels; + + if (y1 < y0) + { + // Switch y1 and y0 + y = y1; + y1 = y0; + y0 = y; + } + + // Check limits + if (y1 >= lcdGetHeight()) + { + y1 = lcdGetHeight() - 1; + } + if (y0 >= lcdGetHeight()) + { + y0 = lcdGetHeight() - 1; + } + + st7735SetAddrWindow(x, y0, x, lcdGetHeight()); + st7735WriteCmd(ST7735_RAMWR); // write to RAM + for (pixels = 0; pixels < y1 - y0 + 1; pixels++) + { + st7735WriteData(color >> 8); + st7735WriteData(color); + } + st7735WriteCmd(ST7735_NOP); +} + +/*************************************************/ +uint16_t lcdGetPixel(uint16_t x, uint16_t y) +{ + // ToDo + return 0; +} + +/*************************************************/ +void lcdSetOrientation(lcdOrientation_t orientation) +{ + // ToDo +} + +/*************************************************/ +lcdOrientation_t lcdGetOrientation(void) +{ + return lcdOrientation; +} + +/*************************************************/ +uint16_t lcdGetWidth(void) +{ + return st7735Properties.width; +} + +/*************************************************/ +uint16_t lcdGetHeight(void) +{ + return st7735Properties.height; +} + +/*************************************************/ +void lcdScroll(int16_t pixels, uint16_t fillColor) +{ + // ToDo +} + +/*************************************************/ +uint16_t lcdGetControllerID(void) +{ + // ToDo + return 0; +} + +/*************************************************/ +lcdProperties_t lcdGetProperties(void) +{ + return st7735Properties; +} diff --git a/drivers/lcd/tft/hw/st7735.h b/drivers/lcd/tft/hw/st7735.h new file mode 100644 index 0000000..483c2cc --- /dev/null +++ b/drivers/lcd/tft/hw/st7735.h @@ -0,0 +1,113 @@ +/**************************************************************************/ +/*! + @file ST7735.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __ST7735_H__ +#define __ST7735_H__ + +#include "projectconfig.h" +#include "drivers/lcd/tft/lcd.h" + +/************************************************************************** + ST7735 CONNECTOR + ----------------------------------------------------------------------- + Pin Function Notes + === ============== =============================== + 1 NC + 2 GND + 3 LED K/- + 4 LED A/+ 3.0V + 5 GND + 6 RESET + 7 RS + 8 SDA Serial Data + 9 SCL Serial Clock + 10 VCC 2.8-3.4V + 11 VCC 2.8-3.4V + 12 CS + 13 GND + 14 NC + + **************************************************************************/ + +// Control pins +#define ST7735_GPIODATAREG (*(pREG32 (0x50023FFC))) // GPIO2DATA +#define ST7735_PORT (2) +#define ST7735_RS_PIN (1) +#define ST7735_SDA_PIN (2) +#define ST7735_SCL_PIN (3) +#define ST7735_CS_PIN (4) +#define ST7735_RES_PIN (5) +#define ST7735_BL_PIN (6) + +// Macros for control line state +#define CLR_RS do { ST7735_GPIODATAREG &= ~(1< 0; t1-- ) + { + __asm("nop"); + } +} + +/*************************************************/ +void st7783WriteCmd(uint16_t command) +{ + // Compiled with -Os on GCC 4.4 this works out to 25 cycles + // (versus 36 compiled with no optimisations). I'm not sure it + // can be improved further, so that means 25 cycles/350nS for + // continuous writes (cmd, data, data, data, ...) or ~150 cycles/ + // ~2.1uS for a random pixel (Set X [cmd+data], Set Y [cmd+data], + // Set color [cmd+data]) (times assumes 72MHz clock). + + CLR_CS_CD_SET_RD_WR; // Saves 18 commands compared to "CLR_CS; CLR_CD; SET_RD; SET_WR;" + ST7783_GPIO2DATA_DATA = (command >> (8 - ST7783_DATA_OFFSET)); + CLR_WR; + SET_WR; + ST7783_GPIO2DATA_DATA = command << ST7783_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR; SET_CS;" +} + +/*************************************************/ +void st7783WriteData(uint16_t data) +{ + CLR_CS_SET_CD_RD_WR; // Saves 18 commands compared to SET_CD; SET_RD; SET_WR; CLR_CS" + ST7783_GPIO2DATA_DATA = (data >> (8 - ST7783_DATA_OFFSET)); + CLR_WR; + SET_WR; + ST7783_GPIO2DATA_DATA = data << ST7783_DATA_OFFSET; + CLR_WR; + SET_WR_CS; // Saves 7 commands compared to "SET_WR, SET_CS;" +} + +/*************************************************/ +uint16_t st7783ReadData(void) +{ + // ToDo: Optimise this method! + + uint16_t high, low; + high = low = 0; + uint16_t d; + + SET_CD_RD_WR; // Saves 14 commands compared to "SET_CD; SET_RD; SET_WR" + CLR_CS; + + // set inputs + ST7783_GPIO2DATA_SETINPUT; + CLR_RD; + st7783Delay(100); + high = ST7783_GPIO2DATA_DATA; + high >>= ST7783_DATA_OFFSET; + high &= 0xFF; + SET_RD; + + CLR_RD; + st7783Delay(100); + low = ST7783_GPIO2DATA_DATA; + low >>= ST7783_DATA_OFFSET; + low &=0xFF; + SET_RD; + + SET_CS; + ST7783_GPIO2DATA_SETOUTPUT; + + d = high; + d <<= 8; + d |= low; + + return d; +} + +/*************************************************/ +uint16_t st7783Read(uint16_t addr) +{ + st7783WriteCmd(addr); + return st7783ReadData(); +} + +/*************************************************/ +void st7783Command(uint16_t command, uint16_t data) +{ + st7783WriteCmd(command); + st7783WriteData(data); +} + +/*************************************************/ +/* Returns the 4-hexdigit controller code */ +/*************************************************/ +uint16_t st7783Type(void) +{ + st7783WriteCmd(0x0); + return st7783ReadData(); +} + +/*************************************************/ +void st7783SetCursor(uint16_t x, uint16_t y) +{ + uint16_t he, ve, al, ah; + + switch (lcdOrientation) + { + case LCD_ORIENTATION_LANDSCAPE: + he = st7783Properties.width-1-y; + ve = st7783Properties.height-1-x; + al = y; + ah = x; + break; + case LCD_ORIENTATION_PORTRAIT: + default: + he = st7783Properties.width-1; + ve = st7783Properties.height-1; + al = x; + ah = y; + break; + } + st7783Command(0x0051, he); + st7783Command(0x0053, ve); + st7783Command(0x0020, al); + st7783Command(0x0021, ah); +} + +/*************************************************/ +void st7783InitDisplay(void) +{ + // Clear data line + GPIO_GPIO2DATA &= ~ST7783_DATA_MASK; + + SET_RD; + SET_WR; + SET_CS; + SET_CD; + + // Reset display + CLR_RESET; + st7783Delay(10000); + SET_RESET; + st7783Delay(500); + + st7783Command(0x00FF, 0x0001); + st7783Command(0x00F3, 0x0008); + st7783WriteCmd(0x00F3); + + st7783Command(0x0001, 0x0100); // Driver Output Control Register (R01h) + st7783Command(0x0002, 0x0700); // LCD Driving Waveform Control (R02h) + st7783Command(0x0003, 0x1030); // Entry Mode (R03h) + st7783Command(0x0008, 0x0302); + st7783Command(0x0009, 0x0000); + st7783Command(0x0010, 0x0000); // Power Control 1 (R10h) + st7783Command(0x0011, 0x0007); // Power Control 2 (R11h) + st7783Command(0x0012, 0x0000); // Power Control 3 (R12h) + st7783Command(0x0013, 0x0000); // Power Control 4 (R13h) + st7783Delay(1000); + st7783Command(0x0010, 0x14B0); // Power Control 1 (R10h) + st7783Delay(500); + st7783Command(0x0011, 0x0007); // Power Control 2 (R11h) + st7783Delay(500); + st7783Command(0x0012, 0x008E); // Power Control 3 (R12h) + st7783Command(0x0013, 0x0C00); // Power Control 4 (R13h) + st7783Command(0x0029, 0x0015); // NVM read data 2 (R29h) + st7783Delay(500); + st7783Command(0x0030, 0x0000); // Gamma Control 1 + st7783Command(0x0031, 0x0107); // Gamma Control 2 + st7783Command(0x0032, 0x0000); // Gamma Control 3 + st7783Command(0x0035, 0x0203); // Gamma Control 6 + st7783Command(0x0036, 0x0402); // Gamma Control 7 + st7783Command(0x0037, 0x0000); // Gamma Control 8 + st7783Command(0x0038, 0x0207); // Gamma Control 9 + st7783Command(0x0039, 0x0000); // Gamma Control 10 + st7783Command(0x003C, 0x0203); // Gamma Control 13 + st7783Command(0x003D, 0x0403); // Gamma Control 14 + st7783Command(0x0050, 0x0000); // Window Horizontal RAM Address Start (R50h) + st7783Command(0x0051, st7783Properties.width - 1); // Window Horizontal RAM Address End (R51h) + st7783Command(0x0052, 0X0000); // Window Vertical RAM Address Start (R52h) + st7783Command(0x0053, st7783Properties.height - 1); // Window Vertical RAM Address End (R53h) + st7783Command(0x0060, 0xa700); // Driver Output Control (R60h) + st7783Command(0x0061, 0x0001); // Driver Output Control (R61h) + st7783Command(0x0090, 0X0029); // Panel Interface Control 1 (R90h) + + // Display On + st7783Command(0x0007, 0x0133); // Display Control (R07h) + st7783Delay(500); + st7783WriteCmd(0x0022); +} + +/*************************************************/ +void st7783Home(void) +{ + st7783SetCursor(0, 0); + st7783WriteCmd(0x0022); // Write Data to GRAM (R22h) +} + +/*************************************************/ +void st7783SetWindow(uint16_t x, uint16_t y, uint16_t height, uint16_t width) +{ + // Window horizontal RAM address start + if (x >= height) st7783Command(0x50, (x - height + 1)); + else st7783Command(0x50, 0); + // Window horizontal GRAM address end + st7783Command(0x51, x); + // Window vertical GRAM address start + if (y >= width) st7783Command(0x52, (y - width + 1)); + else st7783Command(0x52, 0); + // Window vertical GRAM address end + st7783Command(0x53, y); + + st7783SetCursor(x, y); +} + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +/*************************************************/ +void lcdInit(void) +{ + // Set control line pins to output + gpioSetDir(ST7783_CS_PORT, ST7783_CS_PIN, 1); + gpioSetDir(ST7783_CD_PORT, ST7783_CD_PIN, 1); + gpioSetDir(ST7783_WR_PORT, ST7783_WR_PIN, 1); + gpioSetDir(ST7783_RD_PORT, ST7783_RD_PIN, 1); + + // Set data port pins to output + ST7783_GPIO2DATA_SETOUTPUT; + + // Disable pullups + ST7783_DISABLEPULLUPS(); + + // Set backlight pin to output and turn it on + gpioSetDir(ST7783_BL_PORT, ST7783_BL_PIN, 1); // set to output + lcdBacklight(TRUE); + + // Set reset pin to output + gpioSetDir(ST7783_RES_PORT, ST7783_RES_PIN, 1); // Set to output + gpioSetValue(ST7783_RES_PORT, ST7783_RES_PIN, 0); // Low to reset + systickDelay(50); + gpioSetValue(ST7783_RES_PORT, ST7783_RES_PIN, 1); // High to exit + + // Initialize the display + st7783InitDisplay(); + + // Set lcd to default orientation + lcdSetOrientation(lcdOrientation); + + // Fill black + lcdFillRGB(COLOR_BLACK); + + // Initialise the touch screen (and calibrate if necessary) + tsInit(); +} + +/*************************************************/ +void lcdBacklight(bool state) +{ + // Set the backlight + gpioSetValue(ST7783_BL_PORT, ST7783_BL_PIN, state ? 0 : 1); +} + +/*************************************************/ +void lcdTest(void) +{ + uint32_t i,j; + st7783Home(); + + for(i=0;i<320;i++) + { + for(j=0;j<240;j++) + { + if(i>279)st7783WriteData(COLOR_WHITE); + else if(i>239)st7783WriteData(COLOR_BLUE); + else if(i>199)st7783WriteData(COLOR_GREEN); + else if(i>159)st7783WriteData(COLOR_CYAN); + else if(i>119)st7783WriteData(COLOR_RED); + else if(i>79)st7783WriteData(COLOR_MAGENTA); + else if(i>39)st7783WriteData(COLOR_YELLOW); + else st7783WriteData(COLOR_BLACK); + } + } +} + +/*************************************************/ +void lcdFillRGB(uint16_t data) +{ + unsigned int i; + st7783Home(); + + uint32_t pixels = 320*240; + for ( i=0; i < pixels; i++ ) + { + st7783WriteData(data); + } +} + +/*************************************************/ +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + st7783SetCursor(x, y); + st7783WriteCmd(0x0022); // Write Data to GRAM (R22h) + st7783WriteData(color); +} + +/**************************************************************************/ +/*! + @brief Draws an array of consecutive RGB565 pixels (much + faster than addressing each pixel individually) +*/ +/**************************************************************************/ +void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len) +{ + uint32_t i = 0; + st7783SetCursor(x, y); + st7783WriteCmd(0x0022); // Write Data to GRAM (R22h) + do + { + st7783WriteData(data[i]); + i++; + } while (i GENERIC DRAWING --> SPECIFIC HW + CODE --> CODE --> DRIVER +---------------- ---------------- ---------------- + + +drawing.c Generic drawing routines such as drawing pixels, lines, + rectangles, as well as basic text-rendering. + +lcd.h This file contains the prototypes of HW-specific functions + that must be implemented in the LCD driver, since + drawing.c will redirect all requests to these lower level + functions. + +touchscreen.c Contains a very simple example of how to use ADC to read + the current position on a touchscreen. No signal debouncing + takes places, and this code will need to be improved for us + in a real-world situation. + +hw\* HW-specific drivers based on lcd.h \ No newline at end of file diff --git a/drivers/lcd/tft/touchscreen.c b/drivers/lcd/tft/touchscreen.c new file mode 100644 index 0000000..20e9a19 --- /dev/null +++ b/drivers/lcd/tft/touchscreen.c @@ -0,0 +1,609 @@ +/**************************************************************************/ +/*! + @file touchscreen.c + @author K. Townsend (microBuilder.eu) + + Parts copyright (c) 2001, Carlos E. Vidales. All rights reserved. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "touchscreen.h" + +#include "core/adc/adc.h" +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" +#include "drivers/eeprom/eeprom.h" +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/fonts/dejavusans9.h" + +#define TS_LINE1 "Touch the center of" +#define TS_LINE2 "the red circle using" +#define TS_LINE3 "a pen or stylus" + +static bool _tsInitialised = FALSE; +static uint8_t _tsThreshhold = CFG_TFTLCD_TS_DEFAULTTHRESHOLD; +tsPoint_t _tsLCDPoints[3]; +tsPoint_t _tsTSPoints[3]; +tsMatrix_t _tsMatrix; + +/**************************************************************************/ +/* */ +/* ----------------------- Private Methods ------------------------------ */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Reads the current Z/pressure level using the ADC +*/ +/**************************************************************************/ +void tsReadZ(uint32_t* z1, uint32_t* z2) +{ + if (!_tsInitialised) tsInit(); + + // XP = ADC + // XM = GPIO Output Low + // YP = GPIO Output High + // YM = GPIO Input + + TS_XM_FUNC_GPIO; + TS_YP_FUNC_GPIO; + TS_YM_FUNC_GPIO; + + gpioSetDir (TS_XM_PORT, TS_XM_PIN, 1); + gpioSetDir (TS_YP_PORT, TS_YP_PIN, 1); + gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0); + + gpioSetValue(TS_XM_PORT, TS_XM_PIN, 0); // GND + gpioSetValue(TS_YP_PORT, TS_YP_PIN, 1); // 3.3V + + TS_XP_FUNC_ADC; + *z1 = adcRead(TS_XP_ADC_CHANNEL); + + // XP = GPIO Input + // XM = GPIO Output Low + // YP = GPIO Output High + // YM = ADC + + TS_XP_FUNC_GPIO; + gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0); + + TS_YM_FUNC_ADC; + *z2 = adcRead(TS_YM_ADC_CHANNEL); +} + +/**************************************************************************/ +/*! + @brief Reads the current X position using the ADC +*/ +/**************************************************************************/ +uint32_t tsReadX(void) +{ + if (!_tsInitialised) tsInit(); + + // XP = GPIO Output High + // XM = GPIO Output Low + // YP = ADC + // YM = GPIO Input + + TS_XP_FUNC_GPIO; + TS_XM_FUNC_GPIO; + TS_YM_FUNC_GPIO; + + gpioSetDir (TS_XP_PORT, TS_XP_PIN, 1); + gpioSetDir (TS_XM_PORT, TS_XM_PIN, 1); + gpioSetDir (TS_YM_PORT, TS_YM_PIN, 0); + + gpioSetValue(TS_XP_PORT, TS_XP_PIN, 1); // 3.3V + gpioSetValue(TS_XM_PORT, TS_XM_PIN, 0); // GND + + TS_YP_FUNC_ADC; + + // Return the ADC results + return adcRead(TS_YP_ADC_CHANNEL); +} + +/**************************************************************************/ +/*! + @brief Reads the current Y position using the ADC +*/ +/**************************************************************************/ +uint32_t tsReadY(void) +{ + if (!_tsInitialised) tsInit(); + + // YP = GPIO Output High + // YM = GPIO Output Low + // XP = GPIO Input + // XM = ADC + + TS_YP_FUNC_GPIO; + TS_YM_FUNC_GPIO; + TS_XP_FUNC_GPIO; + + gpioSetDir (TS_YP_PORT, TS_YP_PIN, 1); + gpioSetDir (TS_YM_PORT, TS_YM_PIN, 1); + gpioSetDir (TS_XP_PORT, TS_XP_PIN, 0); + + gpioSetValue(TS_YP_PORT, TS_YP_PIN, 1); // 3.3V + gpioSetValue(TS_YM_PORT, TS_YM_PIN, 0); // GND + + TS_XM_FUNC_ADC; + + // Return the ADC results + return adcRead(TS_XM_ADC_CHANNEL); +} + +/**************************************************************************/ +/*! + @brief Centers a line of text horizontally +*/ +/**************************************************************************/ +void tsCalibCenterText(char* text, uint16_t y, uint16_t color) +{ + drawString((lcdGetWidth() - drawGetStringWidth(&dejaVuSans9ptFontInfo, text)) / 2, y, color, &dejaVuSans9ptFontInfo, text); +} + +/**************************************************************************/ +/*! + @brief Renders the calibration screen with an appropriately + placed test point and waits for a touch event +*/ +/**************************************************************************/ +tsTouchData_t tsRenderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius) +{ + drawFill(COLOR_WHITE); + tsCalibCenterText(TS_LINE1, 50, COLOR_GRAY_50); + tsCalibCenterText(TS_LINE2, 65, COLOR_GRAY_50); + tsCalibCenterText(TS_LINE3, 80, COLOR_GRAY_50); + drawCircle(x, y, radius, COLOR_RED); + drawCircle(x, y, radius + 2, COLOR_GRAY_128); + + // Wait for a valid touch events + tsTouchData_t data; + tsTouchError_t error; + bool valid = false; + while (!valid) + { + error = tsRead(&data); + if (!error && data.valid) + { + valid = true; + } + } + + return data; +} + +/**************************************************************************/ +/*! + @brief Calculates the difference between the touch screen and the + actual screen co-ordinates, taking into account misalignment + and any physical offset of the touch screen. + + @note This is based on the public domain touch screen calibration code + written by Carlos E. Vidales (copyright (c) 2001). + + For more inforormation, see the following app notes: + + - AN2173 - Touch Screen Control and Calibration + Svyatoslav Paliy, Cypress Microsystems + - Calibration in touch-screen systems + Wendy Fang and Tony Chang, + Analog Applications Journal, 3Q 2007 (Texas Instruments) +*/ +/**************************************************************************/ +int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr) +{ + int retValue = 0; + + matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - + ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; + + if( matrixPtr->Divider == 0 ) + { + retValue = -1 ; + } + else + { + matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - + ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; + + matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - + ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; + + matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + + (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + + (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; + + matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - + ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; + + matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - + ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; + + matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + + (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + + (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; + + // Persist data to EEPROM + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN, matrixPtr->An); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN, matrixPtr->Bn); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN, matrixPtr->Cn); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN, matrixPtr->Dn); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN, matrixPtr->En); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN, matrixPtr->Fn); + eepromWriteS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER, matrixPtr->Divider); + eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1); + } + + return( retValue ) ; +} + +/**************************************************************************/ +/*! + @brief Converts the supplied touch screen location (screenPtr) to + a pixel location on the display (displayPtr) using the + supplied matrix. The screen orientation is also taken into + account when converting the touch screen co-ordinate to + a pixel location on the LCD. + + @note This is based on the public domain touch screen calibration code + written by Carlos E. Vidales (copyright (c) 2001). +*/ +/**************************************************************************/ +int getDisplayPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr ) +{ + int retValue = 0 ; + + if( matrixPtr->Divider != 0 ) + { + displayPtr->x = ( (matrixPtr->An * screenPtr->x) + + (matrixPtr->Bn * screenPtr->y) + + matrixPtr->Cn + ) / matrixPtr->Divider ; + + displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) + + (matrixPtr->En * screenPtr->y) + + matrixPtr->Fn + ) / matrixPtr->Divider ; + } + else + { + retValue = -1 ; + } + + // Adjust value if the screen is in landscape mode + lcdOrientation_t orientation; + orientation = lcdGetOrientation(); + if (orientation == LCD_ORIENTATION_LANDSCAPE) + { + uint32_t oldx, oldy; + oldx = displayPtr->x; + oldy = displayPtr->y; + displayPtr->x = oldy; + displayPtr->y = lcdGetHeight() - oldx; + } + + return( retValue ) ; +} + +/**************************************************************************/ +/* */ +/* ----------------------- Public Methods ------------------------------- */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/*! + @brief Initialises the appropriate GPIO pins and ADC for the + touchscreen +*/ +/**************************************************************************/ +void tsInit(void) +{ + // Make sure that ADC is initialised + adcInit(); + + // Set initialisation flag + _tsInitialised = TRUE; + _tsThreshhold = tsGetThreshhold(); + + // Load values from EEPROM if touch screen has already been calibrated + if (eepromReadU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED) == 1) + { + // Load calibration data + _tsMatrix.An = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_AN); + _tsMatrix.Bn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_BN); + _tsMatrix.Cn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_CN); + _tsMatrix.Dn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_DN); + _tsMatrix.En = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_EN); + _tsMatrix.Fn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN); + _tsMatrix.Divider = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER); + } +} + +/**************************************************************************/ +/*! + @brief Reads the current X, Y and Z co-ordinates of the touch screen +*/ +/**************************************************************************/ +tsTouchError_t tsRead(tsTouchData_t* data) +{ + uint32_t x1, x2, y1, y2, z1, z2; + + // Assign pressure levels regardless of touch state + tsReadZ(&z1, &z2); + data->z1 = z1; + data->z2 = z2; + data->xraw = 0; + data->yraw = 0; + data->xlcd = 0; + data->ylcd = 0; + + // Abort if the screen is not being touched (0 levels reported) + if (z1 < _tsThreshhold) + { + data->valid = false; + return TS_ERROR_NONE; + } + + // Get two X/Y readings and compare results + x1 = tsReadX(); + x2 = tsReadX(); + y1 = tsReadY(); + y2 = tsReadY(); + + // Throw an error if both readings aren't identical + if (x1 != x2 || y1 != y2) + { + data->valid = false; + data->xraw = x1; + data->yraw = y1; + return TS_ERROR_XYMISMATCH; + } + + // X/Y seems to be valid and reading has been confirmed twice + data->xraw = x1; + data->yraw = y1; + + // Convert x/y values to pixel location with matrix multiply + tsPoint_t location, touch; + touch.x = x1; + touch.y = y1; + getDisplayPoint( &location, &touch, &_tsMatrix) ; + data->xlcd = location.x; + data->ylcd = location.y; + data->valid = true; + + return TS_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Starts the screen calibration process. Each corner will be + tested, meaning that each boundary (top, left, right and + bottom) will be tested twice and the readings averaged. +*/ +/**************************************************************************/ +void tsCalibrate(void) +{ + tsTouchData_t data; + + /* --------------- Welcome Screen --------------- */ + data = tsRenderCalibrationScreen(lcdGetWidth() / 2, lcdGetHeight() / 2, 5); + systickDelay(250); + + /* ----------------- First Dot ------------------ */ + // 10% over and 10% down + data = tsRenderCalibrationScreen(lcdGetWidth() / 10, lcdGetHeight() / 10, 5); + _tsLCDPoints[0].x = lcdGetWidth() / 10; + _tsLCDPoints[0].y = lcdGetHeight() / 10; + _tsTSPoints[0].x = data.xraw; + _tsTSPoints[0].y = data.yraw; + printf("Point 1 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n", + (int)_tsLCDPoints[0].x, (int)_tsLCDPoints[0].y, (int)_tsTSPoints[0].x, (int)_tsTSPoints[0].y); + systickDelay(250); + + /* ---------------- Second Dot ------------------ */ + // 50% over and 90% down + data = tsRenderCalibrationScreen(lcdGetWidth() / 2, lcdGetHeight() - lcdGetHeight() / 10, 5); + _tsLCDPoints[1].x = lcdGetWidth() / 2; + _tsLCDPoints[1].y = lcdGetHeight() - lcdGetHeight() / 10; + _tsTSPoints[1].x = data.xraw; + _tsTSPoints[1].y = data.yraw; + printf("Point 2 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n", + (int)_tsLCDPoints[1].x, (int)_tsLCDPoints[1].y, (int)_tsTSPoints[1].x, (int)_tsTSPoints[1].y); + systickDelay(250); + + /* ---------------- Third Dot ------------------- */ + // 90% over and 50% down + data = tsRenderCalibrationScreen(lcdGetWidth() - lcdGetWidth() / 10, lcdGetHeight() / 2, 5); + _tsLCDPoints[2].x = lcdGetWidth() - lcdGetWidth() / 10; + _tsLCDPoints[2].y = lcdGetHeight() / 2; + _tsTSPoints[2].x = data.xraw; + _tsTSPoints[2].y = data.yraw; + printf("Point 3 - LCD X:%04d Y:%04d TS X:%04d Y:%04d \r\n", + (int)_tsLCDPoints[2].x, (int)_tsLCDPoints[2].y, (int)_tsTSPoints[2].x, (int)_tsTSPoints[2].y); + systickDelay(250); + + // Do matrix calculations for calibration and store to EEPROM + setCalibrationMatrix(&_tsLCDPoints[0], &_tsTSPoints[0], &_tsMatrix); +} + +/**************************************************************************/ +/*! + @brief Causes a blocking delay until a valid touch event occurs + + @note Thanks to 'rossum' and limor for this nifty little tidbit on + debouncing the signals via pressure sensitivity (using Z) + + @section Example + + @code + #include "drivers/lcd/tft/touchscreen.h" + ... + tsTouchData_t data; + tsTouchError_t error; + + while (1) + { + // Cause a blocking delay until a touch event occurs or 5s passes + error = tsWaitForEvent(&data, 5000); + + if (error) + { + switch(error) + { + case TS_ERROR_TIMEOUT: + printf("Timeout occurred %s", CFG_PRINTF_NEWLINE); + break; + default: + break; + } + } + else + { + // A valid touch event occurred ... display data + printf("Touch Event: X = %04u, Y = %04u %s", + data.xlcd, + data.ylcd, + CFG_PRINTF_NEWLINE); + } + } + + @endcode +*/ +/**************************************************************************/ +tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS) +{ + if (!_tsInitialised) tsInit(); + + tsRead(data); + + // Return the results right away if reading is valid + if (data->valid) + { + return TS_ERROR_NONE; + } + + // Handle timeout if delay > 0 milliseconds + if (timeoutMS) + { + uint32_t startTick = systickGetTicks(); + // Systick rollover may occur while waiting for timeout + if (startTick > 0xFFFFFFFF - timeoutMS) + { + while (data->valid == false) + { + // Throw alert if timeout delay has been passed + if ((systickGetTicks() < startTick) && (systickGetTicks() >= (timeoutMS - (0xFFFFFFFF - startTick)))) + { + return TS_ERROR_TIMEOUT; + } + tsRead(data); + } + } + // No systick rollover will occur ... calculate timeout the simple way + else + { + // Wait in infinite loop + while (data->valid == false) + { + // Throw timeout if delay has been passed + if ((systickGetTicks() - startTick) > timeoutMS) + { + return TS_ERROR_TIMEOUT; + } + tsRead(data); + } + } + } + // No timeout requested ... wait forever + else + { + while (data->valid == false) + { + tsRead(data); + } + } + + // Indicate correct reading + return TS_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Updates the touch screen threshhold level and saves it + to EEPROM +*/ +/**************************************************************************/ +int tsSetThreshhold(uint8_t value) +{ + if ((value < 0) || (value > 254)) + { + return -1; + } + + // Update threshhold value + _tsThreshhold = value; + + // Persist to EEPROM + eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_THRESHHOLD, value); + + return 0; +} + +/**************************************************************************/ +/*! + @brief Gets the current touch screen threshhold level from EEPROM + (if present) or returns the default value from projectconfig.h +*/ +/**************************************************************************/ +uint8_t tsGetThreshhold(void) +{ + // Check if custom threshold has been set in eeprom + uint8_t thold = eepromReadU8(CFG_EEPROM_TOUCHSCREEN_THRESHHOLD); + if (thold != 0xFF) + { + // Use value from EEPROM + _tsThreshhold = thold; + } + else + { + // Use the default value from projectconfig.h + _tsThreshhold = CFG_TFTLCD_TS_DEFAULTTHRESHOLD; + } + + return _tsThreshhold; +} diff --git a/drivers/lcd/tft/touchscreen.h b/drivers/lcd/tft/touchscreen.h new file mode 100644 index 0000000..ae49eb2 --- /dev/null +++ b/drivers/lcd/tft/touchscreen.h @@ -0,0 +1,109 @@ +/**************************************************************************/ +/*! + @file touchscreen.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __TOUCHSCREEN_H__ +#define __TOUCHSCREEN_H__ + +#include "projectconfig.h" + +#define TS_XP_PORT (1) +#define TS_XP_PIN (0) +#define TS_XP_FUNC_GPIO do {IOCON_JTAG_TMS_PIO1_0 &= ~(IOCON_JTAG_TMS_PIO1_0_FUNC_MASK | IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK); IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_GPIO;} while (0) +#define TS_XP_FUNC_ADC do {IOCON_JTAG_TMS_PIO1_0 &= ~(IOCON_JTAG_TMS_PIO1_0_FUNC_MASK | IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK); IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_AD1;} while (0) + +#define TS_XM_PORT (1) +#define TS_XM_PIN (1) +#define TS_XM_FUNC_GPIO do {IOCON_JTAG_TDO_PIO1_1 &= ~(IOCON_JTAG_TDO_PIO1_1_FUNC_MASK | IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK); IOCON_JTAG_TDO_PIO1_1 |= IOCON_JTAG_TDO_PIO1_1_FUNC_GPIO;} while (0) +#define TS_XM_FUNC_ADC do {IOCON_JTAG_TDO_PIO1_1 &= ~(IOCON_JTAG_TDO_PIO1_1_FUNC_MASK | IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK); IOCON_JTAG_TDO_PIO1_1 |= IOCON_JTAG_TDO_PIO1_1_FUNC_AD2;} while (0) + +#define TS_YP_PORT (0) +#define TS_YP_PIN (11) +#define TS_YP_FUNC_GPIO do {IOCON_JTAG_TDI_PIO0_11 &= ~(IOCON_JTAG_TDI_PIO0_11_FUNC_MASK | IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK); IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO;} while (0) +#define TS_YP_FUNC_ADC do {IOCON_JTAG_TDI_PIO0_11 &= ~(IOCON_JTAG_TDI_PIO0_11_FUNC_MASK | IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK); IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_AD0;} while (0) + +#define TS_YM_PORT (1) +#define TS_YM_PIN (2) +#define TS_YM_FUNC_GPIO do {IOCON_JTAG_nTRST_PIO1_2 &= ~(IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK | IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK); IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_GPIO;} while (0) +#define TS_YM_FUNC_ADC do {IOCON_JTAG_nTRST_PIO1_2 &= ~(IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK | IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK); IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3;} while (0) + +#define TS_YP_ADC_CHANNEL (0) // ADC0.0 +#define TS_XP_ADC_CHANNEL (1) // ADC0.1 +#define TS_XM_ADC_CHANNEL (2) // ADC0.2 +#define TS_YM_ADC_CHANNEL (3) // ADC0.3 + +typedef struct Point +{ + int32_t x; + int32_t y; +} tsPoint_t; + +typedef struct Matrix +{ + int32_t An, + Bn, + Cn, + Dn, + En, + Fn, + Divider ; +} tsMatrix_t; + +typedef struct +{ + uint32_t xraw; // Touch screen x + uint32_t yraw; // Touch screen Y + uint16_t xlcd; // LCD co-ordinate X + uint16_t ylcd; // LCD co-ordinate Y + uint32_t z1; + uint32_t z2; + bool valid; // Whether this is a valid reading or not +} tsTouchData_t; + +typedef enum +{ + TS_ERROR_NONE = 0, + TS_ERROR_TIMEOUT = -1, // Timeout occured before a valid reading + TS_ERROR_XYMISMATCH = -2 // Unable to get a stable X/Y value +} tsTouchError_t; + +// Method Prototypes +void tsInit ( void ); +tsTouchError_t tsRead(tsTouchData_t* data); +void tsCalibrate ( void ); +tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS); +int tsSetThreshhold(uint8_t value); +uint8_t tsGetThreshhold(void); + +#endif diff --git a/drivers/motor/stepper/stepper.c b/drivers/motor/stepper/stepper.c new file mode 100644 index 0000000..5112fe3 --- /dev/null +++ b/drivers/motor/stepper/stepper.c @@ -0,0 +1,300 @@ +/**************************************************************************/ +/*! + @file stepper.c + @author Based on original code by Tom Igoe + Modified by K. Townsend (microBuilder.eu) + + @brief Simple bi-polar stepper motor controller, based on the + Arduino stepper library by Tom Igoe. Includes simple + position handling methods to keep track of the motor's + relative position and the spindle's current rotation. + + @section Example + + @code + + #include "sysinit.h" + #include "core/systick/systick.h" + #include "drivers/motor/stepper/stepper.h" + + ... + + systemInit(); // Configure cpu and mandatory peripherals + + stepperInit(200); // Initialise driver for 200-step motor + stepperSetSpeed(60); // Set speed to 60 rpm (1 revolution per second) + + while (1) + { + stepperStep(400); // Move forward 400 steps + stepperStep(-200); // Move backward 200 steps + systickDelay(1000); // Wait one second + + // Move 'home' after 10 loops (current position = 2000) + if (stepperGetPosition() == 2000) + { + stepperMoveHome(); // Move back to the starting position + systickDelay(1000); // Wait one second + } + } + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "stepper.h" +#include "core/gpio/gpio.h" +#include "core/timer32/timer32.h" + +static int64_t stepperPosition = 0; // The current position (in steps) relative to 'Home' +static uint32_t stepperStepNumber = 0; // The current position (in steps) relative to 0° +static uint32_t stepperStepsPerRotation = 0; // Number of steps in a full 360° rotation +static uint32_t stepperStepDelay = 0; // Delay in CPU ticks between individual steps + +/**************************************************************************/ +/*! + Private - Cause the motor to step forward or backward one step +*/ +/**************************************************************************/ +void stepMotor(uint32_t thisStep) +{ + switch (thisStep) + { + case 0: // 1010 + gpioSetValue(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 1); + gpioSetValue(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 0); + gpioSetValue(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 1); + gpioSetValue(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 0); + break; + case 1: // 0110 + gpioSetValue(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 0); + gpioSetValue(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 1); + gpioSetValue(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 1); + gpioSetValue(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 0); + break; + case 2: // 0101 + gpioSetValue(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 0); + gpioSetValue(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 1); + gpioSetValue(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 0); + gpioSetValue(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 1); + break; + case 3: // 1001 + gpioSetValue(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 1); + gpioSetValue(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 0); + gpioSetValue(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 0); + gpioSetValue(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 1); + break; + } +} + +/**************************************************************************/ +/*! + @brief Initialises the GPIO pins and delay timer and sets any + default values. + + @param[in] steps + The number of steps per rotation (typically 200 or 400) +*/ +/**************************************************************************/ +void stepperInit(uint32_t steps) +{ + // Setup motor control pins + gpioSetDir(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 1); + gpioSetDir(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 1); + gpioSetDir(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 1); + gpioSetDir(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 1); + + gpioSetValue(STEPPER_IN1_PORT, STEPPER_IN1_PIN, 0); + gpioSetValue(STEPPER_IN2_PORT, STEPPER_IN2_PIN, 0); + gpioSetValue(STEPPER_IN3_PORT, STEPPER_IN3_PIN, 0); + gpioSetValue(STEPPER_IN4_PORT, STEPPER_IN4_PIN, 0); + + // Set the number of steps per rotation + stepperStepsPerRotation = steps; + + // Set the default speed (2 rotations per second) + stepperSetSpeed(120); +} + +/**************************************************************************/ +/*! + @brief Gets the current position (in steps) relative to 'Home'. + + @return The difference (in steps) of the motor's current position + from the original 'Home' position. Value can be negative or + positive depending on the direction of previous movements. +*/ +/**************************************************************************/ +int64_t stepperGetPosition() +{ + return stepperPosition; +} + +/**************************************************************************/ +/*! + @brief Gets the motor's current rotation (in steps) relative to + the spindle's 'Zero' position. + + @return The current step (0 .. steps per rotation) on the motor's + spindle relative to 0°. Value is always positive. +*/ +/**************************************************************************/ +uint32_t stepperGetRotation() +{ + return stepperStepNumber; +} + +/**************************************************************************/ +/*! + @brief Sets the motor's current position to 'Home', meaning that + any future movement will be relative to the current + position. +*/ +/**************************************************************************/ +void stepperSetHome() +{ + stepperPosition = 0; +} + +/**************************************************************************/ +/*! + @brief Moves the motor back to the original 'Home' position. +*/ +/**************************************************************************/ +void stepperMoveHome() +{ + stepperStep(stepperPosition * -1); +} + +/**************************************************************************/ +/*! + @brief Saves the spindle's current angle/position as 0°. Each + step the spindle takes will now be relative to the spindle's + current position. +*/ +/**************************************************************************/ +void stepperSetZero() +{ + stepperStepNumber = 0; +} + +/**************************************************************************/ +/*! + @brief Moves the motor to its original rotation value. For example, + if a 200-step motor is currently rotated to step 137, it + will move the motor forward 63 steps to end at step 0 or 0°. +*/ +/**************************************************************************/ +void stepperMoveZero() +{ + if (!stepperStepNumber) + { + stepperStep(stepperStepsPerRotation - stepperStepNumber); + } +} + +/**************************************************************************/ +/*! + @brief Sets the motor speed in rpm, meaning the number of times the + motor will fully rotate in a one minute period. + + @param[in] rpm + Motor speed in revolutions per minute (RPM) + + @warning Not all motors will function at all speeds, and some trial + and error may be required to find an appropriate speed for + the motor. +*/ +/**************************************************************************/ +void stepperSetSpeed(uint32_t rpm) +{ + uint32_t ticksOneRPM = ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / stepperStepsPerRotation) * 60; + + // Set stepper RPM + stepperStepDelay = ticksOneRPM / rpm; + + // Initialise 32-bit timer 0 with the appropriate delay + timer32Init(0, stepperStepDelay); + timer32Enable(0); +} + +/**************************************************************************/ +/*! + @brief Moves the motor forward or backward the specified number + of steps. A positive number moves the motor forward, + while a negative number moves the motor backwards. + + @param[in] steps + The number of steps to move foreward (positive) or + backward (negative) +*/ +/**************************************************************************/ +void stepperStep(int32_t steps) +{ + uint32_t stepsLeft = abs(steps); // Force number to be positive + + while (stepsLeft > 0) + { + // Wait 1 tick between individual steps + timer32Delay(0, 1); + + // Increment or decrement step counters (depending on direction) + if (steps > 0) + { + stepperPosition++; // Increment global position counter + stepperStepNumber++; // Increment single rotation counter + if (stepperStepNumber == stepperStepsPerRotation) + { + stepperStepNumber = 0; + } + } + else + { + stepperPosition--; // Decrement global position counter + if (stepperStepNumber == 0) + { + stepperStepNumber = stepperStepsPerRotation; + } + stepperStepNumber--; // Decrement single rotation counter + } + + // Decrement number of remaining steps + stepsLeft--; + + // Step the motor one step + stepMotor(stepperStepNumber % 4); + } +} + + + diff --git a/drivers/motor/stepper/stepper.h b/drivers/motor/stepper/stepper.h new file mode 100644 index 0000000..7e4f3d2 --- /dev/null +++ b/drivers/motor/stepper/stepper.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/*! + @file stepper.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _STEPPER_H_ +#define _STEPPER_H_ + +#include "projectconfig.h" + +#define STEPPER_IN1_PORT (3) +#define STEPPER_IN1_PIN (0) +#define STEPPER_IN2_PORT (3) +#define STEPPER_IN2_PIN (1) +#define STEPPER_IN3_PORT (3) +#define STEPPER_IN3_PIN (2) +#define STEPPER_IN4_PORT (3) +#define STEPPER_IN4_PIN (3) + +void stepperInit( uint32_t steps ); +void stepperSetSpeed( uint32_t rpm ); +int64_t stepperGetPosition(); +uint32_t stepperGetRotation(); +void stepperMoveHome(); +void stepperSetHome(); +void stepperMoveZero(); +void stepperSetZero(); +void stepperStep( int32_t steps ); + +#endif \ No newline at end of file diff --git a/drivers/rsa/rsa.c b/drivers/rsa/rsa.c new file mode 100644 index 0000000..9fda5be --- /dev/null +++ b/drivers/rsa/rsa.c @@ -0,0 +1,128 @@ +/**************************************************************************/ +/*! + @file rsa.c + @author Kyle Loudon + modified: microBuilder.eu + @date 4 January, 2010 + @version 1.0 + + Basic RSA-encryption using 64-bit math (32-bit keys). + + Based on the examples from "Mastering Algorithms with C" by + Kyle Loudon (O'Reilly, 1999). + + For details on how to generate a valid RSA key pair, see: + http://www.microbuilder.eu/Tutorials/SoftwareDevelopment/RSAEncryption.aspx + + @warning Most versions of libc used for embedded systems do not + include support for 64-bit integers with printf, etc. (to + keep the compiled code size and memory usage as small as + possible). Unless you have explicitly added long long + support for printf, you should not try to display 64-bit + values with it (%lld, etc.). Using 32-bit values (changing + the definition of huge_t to uint32_t) will avoid this issue + entirely, though at the expense of weaker encryption. +*/ +/**************************************************************************/ + +#include "rsa.h" + +huge_t modexp(huge_t a, huge_t b, huge_t n) +{ + huge_t y; + y = 1; + + /* Compute pow(a, b) % n using the binary square and multiply method. */ + while (b != 0) + { + /* For each 1 in b, accumulate y. */ + if (b & 1) + { + y = (y * a) % n; + } + + /* Square a for each bit in b. */ + a = (a * a) % n; + + /* Prepare for the next bit in b. */ + b = b >> 1; + } + + return y; +} + +void rsaTest() +{ + huge_t rsaOrig, rsaDecrypted, rsaEncrypted; + rsaPubKey_t publicKey; + rsaPriKey_t privateKey; + int i; + + printf("Encrypting with RSA %s", CFG_PRINTF_NEWLINE); + + #if CFG_RSA_BITS == 64 + // Values based on 64-bit math (huge_t = uint64_t) + // which will result in more secure encryption, but also + // increases the size of the encrypted text + publicKey.e = 21; + publicKey.n = 16484947; + privateKey.d = 15689981; + privateKey.n = 16484947; + #endif + + #if CFG_RSA_BITS == 32 + // Alternative values with 32-bit math (huge_t = uint32_t) + // or when smaller encrypted text is desired + publicKey.e = 17; + publicKey.n = 209; + privateKey.d = 53; + privateKey.n = 209; + #endif + + #if CFG_RSA_BITS == 64 + printf("Starting RSA encryption/decryption test %s", CFG_PRINTF_NEWLINE); + #endif + #if CFG_RSA_BITS == 32 + printf("d=%u, e=%u, n=%u %s", (unsigned int)privateKey.d, (unsigned int)publicKey.e, (unsigned int)publicKey.n, CFG_PRINTF_NEWLINE); + #endif + + for (i = 0; i < 128; i++) + { + rsaOrig = i; + rsaEncrypt(rsaOrig, &rsaEncrypted, publicKey); + rsaDecrypt(rsaEncrypted, &rsaDecrypted, privateKey); + + if (rsaOrig == rsaDecrypted) + { + #if CFG_RSA_BITS == 64 + printf("Encrypted and decrypted %d %s", i, CFG_PRINTF_NEWLINE); + #endif + #if CFG_RSA_BITS == 32 + printf("In=%5u, Encrypted=%5u, Out=%5u (OK) %s", (unsigned int)rsaOrig, (unsigned int)rsaEncrypted, (unsigned int)rsaDecrypted, CFG_PRINTF_NEWLINE); + #endif + } + else + { + #if CFG_RSA_BITS == 64 + printf("Failed to decrypt %d %s", i, CFG_PRINTF_NEWLINE); + #endif + #if CFG_RSA_BITS == 32 + printf("In=%5u, Encrypted=%5u, Out=%5u (ERROR) %s", (unsigned int)rsaOrig, (unsigned int)rsaEncrypted, (unsigned int)rsaDecrypted, CFG_PRINTF_NEWLINE); + #endif + } + } +} + +void rsaEncrypt(huge_t plaintext, huge_t *ciphertext, rsaPubKey_t pubkey) +{ + *ciphertext = modexp(plaintext, pubkey.e, pubkey.n); + + return; +} + +void rsaDecrypt(huge_t ciphertext, huge_t *plaintext, rsaPriKey_t prikey) +{ + *plaintext = modexp(ciphertext, prikey.d, prikey.n); + + return; +} diff --git a/drivers/rsa/rsa.h b/drivers/rsa/rsa.h new file mode 100644 index 0000000..a879f0b --- /dev/null +++ b/drivers/rsa/rsa.h @@ -0,0 +1,51 @@ +/**************************************************************************/ +/*! + @file rsa.h + @author Kyle Loudon + modified: microBuilder.eu + @date 4 January, 2010 + @version 1.0 + + Basic RSA-encryption using 64-bit math (32-bit keys). + + Based on the examples from "Mastering Algorithms with C" by + Kyle Loudon (O'Reilly, 1999). +*/ +/**************************************************************************/ + +#ifndef _RSA_H_ +#define _RSA_H_ + +#include "projectconfig.h" + +/* In a secure implementation, huge_t should be at least 400 decimal digits, * + * instead of the 20 provided by a 64-bit value. This means that key values * + * can be no longer than 10 digits in length in the current implementation. */ +#if CFG_RSA_BITS == 64 + typedef uint64_t huge_t; +#endif +#if CFG_RSA_BITS == 32 + typedef uint32_t huge_t; +#endif + +/* Structure for RSA public keys. */ +typedef struct rsaPubKey_s +{ + huge_t e; + huge_t n; +} +rsaPubKey_t; + +/* Define a structure for RSA private keys. */ +typedef struct rsaPriKey_s +{ + huge_t d; + huge_t n; +} +rsaPriKey_t; + +void rsaTest(); +void rsaEncrypt(huge_t plaintext, huge_t *ciphertext, rsaPubKey_t pubkey); +void rsaDecrypt(huge_t ciphertext, huge_t *plaintext, rsaPriKey_t prikey); + +#endif diff --git a/drivers/sensors/analogjoystick/analogjoystick.c b/drivers/sensors/analogjoystick/analogjoystick.c new file mode 100644 index 0000000..3a1cd5c --- /dev/null +++ b/drivers/sensors/analogjoystick/analogjoystick.c @@ -0,0 +1,138 @@ +/**************************************************************************/ +/*! + @file analogjoystick.c + @author K. Townsend (microBuilder.eu) + + @section DESCRIPTION + + Driver for a simple four-way analog joystick. + + @section Example + + @code + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "analogjoystick.h" +#include "core/adc/adc.h" +#include "core/gpio/gpio.h" + +static bool _joystickInitialised = false; + +/**************************************************************************/ +/*! + @brief Initialises the analog joystick, setting the appropriate + pins to analog and digital input. +*/ +/**************************************************************************/ +void joystickInit(void) +{ + // Make sure SEL is set to GPIO and input + JOYSTICK_SEL_FUNC_GPIO; + gpioSetDir (JOYSTICK_SEL_PORT, JOYSTICK_SEL_PIN, 0); + + // Make sure that ADC is initialised + adcInit(); + + // Set HORIZ/VERT pins to ADC + JOYSTICK_VERT_FUNC_ADC; + JOYSTICK_HORIZ_FUNC_ADC; + + _joystickInitialised = true; +} + +/**************************************************************************/ +/*! + @brief Gets the raw ADC values for the horizontal and vertical + axis, as well as the current state of the select button. + + @param[out] horizontal + pointer to the uint32_t variable that will hold the + results of the horizontal analog conversion + @param[out] vertical + pointer to the uint32_t variable that will hold the + results of the vertical analog conversion + @param[out] select + pointer to the bool variable that will hold the + current state of the digital select button +*/ +/**************************************************************************/ +void joystickGetValues(uint32_t *horizontal, uint32_t *vertical, bool *select) +{ + if (!_joystickInitialised) joystickInit(); + + // Get current ADC values + *horizontal = adcRead(JOYSTICK_HORIZ_ADCPORT); + *vertical = adcRead(JOYSTICK_VERT_ADCPORT); + *select = gpioGetValue(JOYSTICK_SEL_PORT, JOYSTICK_SEL_PIN); +} + +/**************************************************************************/ +/*! + @brief Gets the rough direction that the joystick is currently + positioned at + + @param[out] direction + The joystick_direction_t (enum) that will be used to + identify the joysticks approximate current direction. +*/ +/**************************************************************************/ +void joystickGetDirection(joystick_direction_t *direction) +{ + if (!_joystickInitialised) joystickInit(); + + uint32_t hor, ver; + bool sel; + + // Get current joystick position + joystickGetValues(&hor, &ver, &sel); + + // ToDo: Process values + direction = JOYSTICK_DIR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the approximate rotation of the joystick from 0-359° in + a clock-wise direction. + + @param[out] rotation + Pointer to the uint32_t variable that will hold the + rotation value. +*/ +/**************************************************************************/ +void joystickGetRotation(uint32_t *rotation) +{ + if (!_joystickInitialised) joystickInit(); + + // ToDo +} diff --git a/drivers/sensors/analogjoystick/analogjoystick.h b/drivers/sensors/analogjoystick/analogjoystick.h new file mode 100644 index 0000000..9574bd6 --- /dev/null +++ b/drivers/sensors/analogjoystick/analogjoystick.h @@ -0,0 +1,69 @@ +/**************************************************************************/ +/*! + @file analogjoystick.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _ANALOGJOYSTICK_H_ +#define _ANALOGJOYSTICK_H_ + +#include "projectconfig.h" + +#define JOYSTICK_VERT_ADCPORT (2) // ADC2 +#define JOYSTICK_HORIZ_ADCPORT (3) // ADC3 +#define JOYSTICK_SEL_PORT (0) // Use UART CTS for SEL input (P0.7) +#define JOYSTICK_SEL_PIN (7) + +#define JOYSTICK_SEL_FUNC_GPIO do {IOCON_PIO0_7 &= ~IOCON_PIO0_7_FUNC_MASK; IOCON_PIO0_7 |= IOCON_PIO0_7_FUNC_GPIO;} while (0) +#define JOYSTICK_VERT_FUNC_ADC do {IOCON_JTAG_TMS_PIO1_0 &= ~IOCON_JTAG_TMS_PIO1_0_FUNC_MASK; IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_AD1;} while (0) +#define JOYSTICK_HORIZ_FUNC_ADC do {IOCON_JTAG_nTRST_PIO1_2 &= ~IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK; IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3;} while (0) + +typedef enum +{ + JOYSTICK_DIR_NONE = 0, + JOYSTICK_DIR_NORTH = 1, + JOYSTICK_DIR_NORTHEAST = 2, + JOYSTICK_DIR_EAST = 3, + JOYSTICK_DIR_SOUTHEAST = 4, + JOYSTICK_DIR_SOUTH = 5, + JOYSTICK_DIR_SOUTHWEST = 6, + JOYSTICK_DIR_WEST = 7, + JOYSTICK_DIR_NORTHWEST = 8 +} joystick_direction_t; + +void joystickInit(void); +void joystickGetValues(uint32_t *horizontal, uint32_t *vertical, bool *select); +void joystickGetDirection(joystick_direction_t *direction); +void joystickGetRotation(uint32_t *rotation); + +#endif diff --git a/drivers/sensors/lm75b/lm75b.c b/drivers/sensors/lm75b/lm75b.c new file mode 100644 index 0000000..d5633d9 --- /dev/null +++ b/drivers/sensors/lm75b/lm75b.c @@ -0,0 +1,208 @@ +/**************************************************************************/ +/*! + @file lm75b.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + Driver for NXP's LM75B I2C temperature sensor. This temperature + sensor has an accuracy of 0.125°C, and returns a temperature value + in degrees celsius where each unit is equal to 0.125°C. For example, + if the temperature reading is 198, it means that the temperature in + degree celsius is: 198 / 8 = 24.75°C. + + @section Example + + @code + #include "core/cpu/cpu.h" + #include "drivers/sensors/lm75b/lm75b.h" + + int main(void) + { + cpuInit(); + + int32_t temp = 0; + + // Initialise the LM75B + lm75bInit(); + + while (1) + { + // Get the current temperature (in 0.125°C units) + lm75bGetTemperature(&temp); + + // Multiply value by 125 for fixed-point math (0.125°C per unit) + temp *= 125; + + // Use modulus operator to display decimal value + printf("Current Temperature: %d.%d C\n", temp / 1000, temp % 1000); + + // Alternatively, you could also use floating point math, though + // this will result in larger compiled code if you add in floating + // point support for printf, etc. + // + // float tempFloat = 0.0F; + // lm75bGetTemperature(&temp); + // tempFloat = (float)temp / 8.0F; + } + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include "lm75b.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +uint32_t i; + +static bool _lm75bInitialised = false; + +/**************************************************************************/ +/*! + @brief Writes an 8 bit values over I2C +*/ +/**************************************************************************/ +lm75bError_e lm75bWrite8 (uint8_t reg, uint32_t value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 3; + I2CReadLength = 0; + I2CMasterBuffer[0] = LM75B_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + I2CMasterBuffer[2] = (value & 0xFF); // Value to write + i2cEngine(); + return LM75B_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Reads a 16 bit values over I2C +*/ +/**************************************************************************/ +lm75bError_e lm75bRead16(uint8_t reg, int32_t *value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 2; + I2CMasterBuffer[0] = LM75B_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + // Append address w/read bit + I2CMasterBuffer[2] = LM75B_ADDRESS | LM75B_READBIT; + i2cEngine(); + + // Shift values to create properly formed integer + *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]) >> 5; + + // Sign extend negative numbers + if (I2CSlaveBuffer[0] & 0x80) + { + // Negative number + *value |= 0xFFFFFC00; + } + return LM75B_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Initialises the I2C block +*/ +/**************************************************************************/ +lm75bError_e lm75bInit(void) +{ + // Initialise I2C + if (i2cInit(I2CMASTER) == false) + { + return LM75B_ERROR_I2CINIT; /* Fatal error */ + } + + _lm75bInitialised = true; + + return LM75B_ERROR_OK; + + // Set device to shutdown mode by default (saves power) + return lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_SHUTDOWN); +} + +/**************************************************************************/ +/*! + @brief Reads the current temperature from the LM75B + + @note This method will assign a signed 32-bit value (int32) to 'temp', + where each unit represents +/- 0.125°C. To convert the numeric + value to degrees celsius, you must divide the value of 'temp' + by 8. This conversion is not done automatically, since you may + or may not want to use floating point math for the calculations. +*/ +/**************************************************************************/ +lm75bError_e lm75bGetTemperature (int32_t *temp) +{ + if (!_lm75bInitialised) lm75bInit(); + + // Turn device on + lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_POWERON); + + // Read temperature + lm75bError_e error = LM75B_ERROR_OK; + error = lm75bRead16 (LM75B_REGISTER_TEMPERATURE, temp); + + // Shut device back down + lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_SHUTDOWN); + + return error; +} + +/**************************************************************************/ +/*! + @brief Writes the supplied 8-bit value to the LM75B config register +*/ +/**************************************************************************/ +lm75bError_e lm75bConfigWrite (uint8_t configValue) +{ + if (!_lm75bInitialised) lm75bInit(); + + return lm75bWrite8 (LM75B_REGISTER_CONFIGURATION, configValue); +} diff --git a/drivers/sensors/lm75b/lm75b.h b/drivers/sensors/lm75b/lm75b.h new file mode 100644 index 0000000..5d6c67c --- /dev/null +++ b/drivers/sensors/lm75b/lm75b.h @@ -0,0 +1,70 @@ +/**************************************************************************/ +/*! + @file lm75b.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _LM75B_H_ +#define _LM75B_H_ + +#include "projectconfig.h" +#include "core/i2c/i2c.h" + +#define LM75B_ADDRESS (0x90) // 100 1000 shifted left 1 bit = 0x90 +#define LM75B_READBIT (0x01) + +#define LM75B_REGISTER_TEMPERATURE (0x00) +#define LM75B_REGISTER_CONFIGURATION (0x01) + +#define LM75B_CONFIG_SHUTDOWN_MASK (0x01) +#define LM75B_CONFIG_SHUTDOWN_POWERON (0x00) +#define LM75B_CONFIG_SHUTDOWN_SHUTDOWN (0x01) + +typedef enum +{ + LM75B_ERROR_OK = 0, // Everything executed normally + LM75B_ERROR_I2CINIT, // Unable to initialise I2C + LM75B_ERROR_I2CBUSY, // I2C already in use + LM75B_ERROR_LAST +} +lm75bError_e; + +lm75bError_e lm75bInit(void); +lm75bError_e lm75bGetTemperature (int32_t *temp); +lm75bError_e lm75bConfigWrite (uint8_t configValue); + +#endif + + diff --git a/drivers/sensors/pn532/pn532.c b/drivers/sensors/pn532/pn532.c new file mode 100644 index 0000000..350d4cb --- /dev/null +++ b/drivers/sensors/pn532/pn532.c @@ -0,0 +1,152 @@ +/**************************************************************************/ +/*! + @file pn532.c +*/ +/**************************************************************************/ +#include + +#include "pn532.h" +#include "pn532_drvr.h" +#include "core/systick/systick.h" +#include "core/uart/uart.h" + +static pn532_pcb_t pcb; + +/**************************************************************************/ +/*! + @brief Prints a hexadecimal value in plain characters + + @param pbtData Pointer to the byte data + @param szBytes Data length in bytes +*/ +/**************************************************************************/ +void pn532PrintHex(const byte_t * pbtData, const size_t szBytes) +{ + size_t szPos; + for (szPos=0; szPos < szBytes; szPos++) + { + PN532_DEBUG("%02x ", pbtData[szPos]); + } + PN532_DEBUG(CFG_PRINTF_NEWLINE); +} + +/**************************************************************************/ +/*! + @brief Gets a reference to the PN532 peripheral control block, + which can be used to determine that state of the PN532 + IC, buffers, etc. +*/ +/**************************************************************************/ +pn532_pcb_t * pn532GetPCB() +{ + return &pcb; +} + +/**************************************************************************/ +/*! + @brief Initialises the appropriate serial bus (UART, etc.),and + sets up any buffers or peripherals required by the PN532. +*/ +/**************************************************************************/ +void pn532Init(void) +{ + // Clear protocol control blocks + memset(&pcb, 0, sizeof(pn532_pcb_t)); + + // Initialise the underlying HW + pn532HWInit(); + + // Set the PCB flags to an appropriate state + pcb.initialised = TRUE; +} + +/**************************************************************************/ +/*! + @brief Configures the PN532 for a specific modulation and + baud rate +*/ +/**************************************************************************/ +pn532_error_t pn532Configure(pn532_modulation_t mod) +{ + // ToDo + + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the response buffer from the PN532 + + @param abtCommand + The byte array containg the command and any + optional paramaters + @param szLen + The number of bytes in abtCommand +*/ +/**************************************************************************/ +pn532_error_t pn532Read(byte_t * abtResponse, size_t * pszLen) +{ + if (!pcb.initialised) pn532Init(); + + // Try to wake the device up if it's in sleep mode + if (pcb.state == PN532_STATE_SLEEP) + { + pn532_error_t wakeupError = pn532Wakeup(); + if (wakeupError) + { + return wakeupError; + } + } + + // Read the response if the device is in an appropriate state + if (pcb.state == PN532_STATE_READY) + { + return pn532ReadResponse(abtResponse, pszLen); + } + else + { + PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE); + return PN532_ERROR_UNABLETOINIT; + } +} + +/**************************************************************************/ +/*! + @brief Sends a byte array of command and parameter data to the + PN532, starting with the command byte. The frame's + preamble, checksums, postamble and frame identifier (0xD4) + will all be automatically added. + + @param abtCommand + The byte array containg the command and any + optional paramaters + @param szLen + The number of bytes in abtCommand +*/ +/**************************************************************************/ +pn532_error_t pn532Write(byte_t * abtCommand, size_t szLen) +{ + if (!pcb.initialised) pn532Init(); + + // Try to wake the device up if it's in sleep mode + if (pcb.state == PN532_STATE_SLEEP) + { + pn532_error_t wakeupError = pn532Wakeup(); + if (wakeupError) + { + return wakeupError; + } + } + + // Send the command if the device is in an appropriate state + if (pcb.state == PN532_STATE_READY) + { + return pn532SendCommand(abtCommand, szLen); + } + else + { + PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE); + return PN532_ERROR_UNABLETOINIT; + } +} + diff --git a/drivers/sensors/pn532/pn532.h b/drivers/sensors/pn532/pn532.h new file mode 100644 index 0000000..a88f06b --- /dev/null +++ b/drivers/sensors/pn532/pn532.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/*! + @file pn532.h +*/ +/**************************************************************************/ + +#ifndef __PN532_H__ +#define __PN532_H__ + +#include "projectconfig.h" + +#define PN532_DEBUG(fmt, args...) printf(fmt, ##args) + +typedef enum pn532_state_e +{ + PN532_STATE_SLEEP, + PN532_STATE_READY, + PN532_STATE_BUSY +} +pn532_state_t; + +/* Error messages generate by the stack (not to be confused with app level errors from the PN532) */ +typedef enum pn532_error_e +{ + PN532_ERROR_NONE = 0x00, + PN532_ERROR_UNABLETOINIT = 0x01, // Unable to initialise or wakeup the device + PN532_ERROR_APPLEVELERROR = 0x02, // Application level error detected + PN532_ERROR_BUSY = 0x03, // Busy executing a previous command + PN532_ERROR_NOACK = 0x04, // No ack message received + PN532_ERROR_INVALIDACK = 0x05, // Ack != 00 00 FF 00 FF 00 + PN532_ERROR_PREAMBLEMISMATCH = 0x06, // Frame preamble + start code mismatch + PN532_ERROR_EXTENDEDFRAME = 0x07, // Extended frames currently unsupported + PN532_ERROR_LENCHECKSUMMISMATCH = 0x08, + PN532_ERROR_RESPONSEBUFFEREMPTY = 0x09, // No response data received + PN532_ERROR_SPIREADYSTATUSTIMEOUT = 0x0A // Timeout waiting for 'ready' status (SPI only) + +} pn532_error_t; + +typedef enum pn532_modulation_e +{ + PN532_MODULATION_ISO14443A_106KBPS = 0x00, + PN532_MODULATION_FELICA_212KBPS = 0x01, + PN532_MODULATION_FELICA_424KBPS = 0x02, + PN532_MODULATION_ISO14443B_106KBPS = 0x03, + PN532_MODULATION_JEWEL_106KBPS = 0x04 +} pn532_modulation_t; + +/* PN532 Protocol control block */ +typedef struct +{ + BOOL initialised; + pn532_state_t state; + pn532_modulation_t modulation; + uint32_t lastCommand; + uint32_t appError; +} pn532_pcb_t; + +void pn532Init(); +pn532_pcb_t * pn532GetPCB(); +pn532_error_t pn532SetModulation(pn532_modulation_t mod); +pn532_error_t pn532Write(byte_t *abtCommand, size_t szLen); +pn532_error_t pn532Read(byte_t *abtResponse, size_t * pszLen); +void pn532PrintHex(const byte_t * pbtData, const size_t szBytes); + +#endif diff --git a/drivers/sensors/pn532/pn532_drvr.h b/drivers/sensors/pn532/pn532_drvr.h new file mode 100644 index 0000000..f314fa1 --- /dev/null +++ b/drivers/sensors/pn532/pn532_drvr.h @@ -0,0 +1,103 @@ +/**************************************************************************/ +/*! + @file pn532_drvr.h +*/ +/**************************************************************************/ + +#ifndef __PN532_DRV_H__ +#define __PN532_DRV_H__ + +#include "projectconfig.h" +#include "pn532.h" + +#define PN532_UART +// #define PN532_SPI + +#define PN532_DEBUG(fmt, args...) printf(fmt, ##args) + +#define PN532_RSTPD_PORT (2) +#define PN532_RSTPD_PIN (2) +#define PN532_SPI_CSPORT (0) +#define PN532_SPI_CSPIN (2) + +#define PN532_NORMAL_FRAME__DATA_MAX_LEN (254) +#define PN532_NORMAL_FRAME__OVERHEAD (8) +#define PN532_EXTENDED_FRAME__DATA_MAX_LEN (264) +#define PN532_EXTENDED_FRAME__OVERHEAD (11) +#define PN532_BUFFER_LEN (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD) +#define PN532_UART_BAUDRATE (115200) + +enum +{ + PN532_COMMAND_DIAGNOSE = 0x00, + PN532_COMMAND_GETFIRMWAREVERSION = 0x02, + PN532_COMMAND_GETGENERALSTATUS = 0x04, + PN532_COMMAND_READREGISTER = 0x06, + PN532_COMMAND_WRITEREGISTER = 0x08, + PN532_COMMAND_READGPIO = 0x0C, + PN532_COMMAND_WRITEGPIO = 0x0E, + PN532_COMMAND_SETSERIALBAUDRATE = 0x10, + PN532_COMMAND_SETPARAMETERS = 0x12, + PN532_COMMAND_SAMCONFIGURATION = 0x14, + PN532_COMMAND_POWERDOWN = 0x16, + PN532_COMMAND_RFCONFIGURATION = 0x32, + PN532_COMMAND_RFREGULATIONTEST = 0x58, + PN532_COMMAND_INJUMPFORDEP = 0x56, + PN532_COMMAND_INJUMPFORPSL = 0x46, + PN532_COMMAND_INLISTPASSIVETARGET = 0x4A, + PN532_COMMAND_INATR = 0x50, + PN532_COMMAND_INPSL = 0x4E, + PN532_COMMAND_INDATAEXCHANGE = 0x40, + PN532_COMMAND_INCOMMUNICATETHRU = 0x42, + PN532_COMMAND_INDESELECT = 0x44, + PN532_COMMAND_INRELEASE = 0x52, + PN532_COMMAND_INSELECT = 0x54, + PN532_COMMAND_INAUTOPOLL = 0x60, + PN532_COMMAND_TGINITASTARGET = 0x8C, + PN532_COMMAND_TGSETGENERALBYTES = 0x92, + PN532_COMMAND_TGGETDATA = 0x86, + PN532_COMMAND_TGSETDATA = 0x8E, + PN532_COMMAND_TGSETMETADATA = 0x94, + PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88, + PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90, + PN532_COMMAND_TGGETTARGETSTATUS = 0x8A +}; + +/* Application level errors generated by the PN532 chip */ +enum +{ + PN532_APPERROR_NONE = 0x00, + PN532_APPERROR_TIMEOUT = 0x01, + PN532_APPERROR_CRCERROR = 0x02, + PN532_APPERROR_PARITYERROR = 0x04, + PN532_APPERROR_FRAMINGERROR = 0x05, + PN532_APPERROR_BITCOLLISION = 0x06, + PN532_APPERROR_INSUFFICIENTBUFFER = 0x07, + PN532_APPERROR_RFBUFFEROVERFLOW = 0x09, + PN532_APPERROR_RFFIELDTIMEOUT = 0x0A, + PN532_APPERROR_RFPROTOCOLERROR = 0x0B, + PN532_APPERROR_TEMPERROR = 0x0D, + PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E, + PN532_APPERROR_INVALIDPARAMETER = 0x10, + PN532_APPERROR_DEP_UNSUPPORTEDCMD = 0x12, + PN532_APPERROR_DEP_INVALIDOFORMAT = 0x13, + PN532_APPERROR_AUTHENTERR = 0x14, + PN532_APPERROR_UIDCCHECKERROR = 0x23, + PN532_APPERROR_DEP_INVALIDDEVSTATE = 0x25, + PN532_APPERROR_OPERATIONNOTALLOWED = 0x26, + PN532_APPERROR_CMDNOTACCEPTABLE = 0x27, + PN532_APPERROR_TARGETRELEASED = 0x29, + PN532_APPERROR_IDMISMATCH = 0x2A, + PN532_APPERROR_CARDDISAPPEARED = 0x2B, + PN532_APPERROR_NFCID3MISMATCH = 0x2C, + PN532_APPERROR_OVERCURRENTEVENT = 0x2D, + PN532_APPERROR_NADMISSINGINDEP = 0x2E +}; + +void pn532HWInit(void); +pn532_error_t pn532BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData); +pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData); +pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen); +pn532_error_t pn532Wakeup(void); + +#endif diff --git a/drivers/sensors/pn532/pn532_drvr_spi.c b/drivers/sensors/pn532/pn532_drvr_spi.c new file mode 100644 index 0000000..f55621a --- /dev/null +++ b/drivers/sensors/pn532/pn532_drvr_spi.c @@ -0,0 +1,410 @@ +/**************************************************************************/ +/*! + @file pn532_drvr_spi.c +*/ +/**************************************************************************/ +#include "pn532_drvr.h" + +#ifdef PN532_SPI + +#include +#include "core/systick/systick.h" +#include "core/gpio/gpio.h" +#include "core/ssp/ssp.h" + +#define PN532_SELECT gpioSetValue(PN532_SPI_CSPORT, PN532_SPI_CSPIN, 0); +#define PN532_DESELECT gpioSetValue(PN532_SPI_CSPORT, PN532_SPI_CSPIN, 1); + +#define PN532_SPI_STATREAD 0x02 +#define PN532_SPI_DATAWRITE 0x01 +#define PN532_SPI_DATAREAD 0x03 +#define PN532_SPI_READY 0x01 + +// The number of attempts to make while waiting for the status ready bit +// Each attempt is 1ms +#define PN532_SPI_TIMEOUT 100 + +/**************************************************************************/ +/*! + @brief Writes a single byte via SPI +*/ +/**************************************************************************/ +uint8_t pn532SPIWrite(unsigned char data) +{ + // Note: bits have to be reversed since SPI is LSB on the PN532 + // Thankfully the M3 has a quick HW reverse command (RBIT) + while ((SSP_SSP0SR & SSP_SSP0SR_TNF_NOTFULL) == 0); + SSP_SSP0DR = ((unsigned char)(RBIT(data)>>24)); // Write + while ((SSP_SSP0SR & SSP_SSP0SR_RNE_NOTEMPTY) == 0); + data = ((unsigned char)(RBIT(SSP_SSP0DR)>>24)); // Read + return data; +} + +/**************************************************************************/ +/*! + @brief Writes a byte array via SPI +*/ +/**************************************************************************/ +void pn532SPIWriteArray(byte_t * pbtData, size_t len) +{ + while (len != 0) + { + pn532SPIWrite(*pbtData); + pbtData++; + len--; + } +} + +/**************************************************************************/ +/*! + @brief Reads a single byte via SPI +*/ +/**************************************************************************/ +uint8_t pn532SPIRead(void) +{ + return pn532SPIWrite(0x00); +} + +/**************************************************************************/ +/*! + @brief Reads a byte array via SPI +*/ +/**************************************************************************/ +void pn532SPIReadArray(uint8_t* buff, size_t len) +{ + size_t i; + for (i=0; i PN532_NORMAL_FRAME__DATA_MAX_LEN) + { + // Extended frames currently unsupported + return PN532_ERROR_EXTENDEDFRAME; + } + + // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1) + pbtFrame[3] = szData + 1; + // LCS - Packet length checksum + pbtFrame[4] = 256 - (szData + 1); + // TFI + pbtFrame[5] = 0xD4; + // DATA - Copy the PN53X command into the packet buffer + memcpy (pbtFrame + 6, pbtData, szData); + + // DCS - Calculate data payload checksum + byte_t btDCS = (256 - 0xD4); + size_t szPos; + for (szPos = 0; szPos < szData; szPos++) + { + btDCS -= pbtData[szPos]; + } + pbtFrame[6 + szData] = btDCS; + + // 0x00 - End of stream marker + pbtFrame[szData + 7] = 0x00; + + (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD; + + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sends the specified command to the PN532, automatically + creating an appropriate frame for it + + @param pdbData Pointer to the byte data to send + @param szData Length in bytes of the data to send + + @note Possible error messages are: + + - PN532_ERROR_BUSY + - PN532_ERROR_NOACK + - PN532_ERROR_INVALIDACK + - PN532_ERROR_SPIREADYSTATUSTIMEOUT +*/ +/**************************************************************************/ +pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData) +{ + pn532_pcb_t *pn532 = pn532GetPCB(); + + // Check busy flag + if (pn532->state == PN532_STATE_BUSY) + { + return PN532_ERROR_BUSY; + } + pn532->state = PN532_STATE_BUSY; + + // Every packet must start with "00 00 ff" + byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; + size_t szFrame = 0; + + // Build the frame + pn532BuildFrame (abtFrame, &szFrame, pbtData, szData); + + // Register the last command that was sent + pn532->lastCommand = pbtData[0]; + + // Output the frame data for debugging if requested + PN532_DEBUG("Sending (%02d): ", szFrame); + pn532PrintHex(abtFrame, szFrame); + + PN532_SELECT; + systickDelay(5); + + // Send data to the PN532 + pn532SPIWrite(PN532_SPI_DATAWRITE); + pn532SPIWriteArray(abtFrame, szFrame); + + // Wait for READY status + size_t t = 0; + while (pn532GetStatus() != PN532_SPI_READY) + { + if(t++>PN532_SPI_TIMEOUT) + { + PN532_DEBUG("Timeout waiting for READY status%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_SPIREADYSTATUSTIMEOUT; + } + systickDelay(1); + } + + // Read ACK + PN532_SELECT; + pn532SPIWrite(PN532_SPI_DATAREAD); + const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; + byte_t abtRxBuf[6]; + pn532SPIReadArray(abtRxBuf, 6); + PN532_DESELECT; + + // Make sure the received ACK matches the prototype + if (0 != (memcmp (abtRxBuf, abtAck, 6))) + { + PN532_DEBUG ("Invalid ACK: "); + pn532PrintHex(abtRxBuf, 6); + PN532_DEBUG("%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_INVALIDACK; + } + + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads a response from the PN532 + + @note Possible error message are: + + - PN532_ERROR_BUSY + - PN532_ERROR_RESPONSEBUFFEREMPTY + - PN532_ERROR_PREAMBLEMISMATCH + - PN532_ERROR_APPLEVELERROR + - PN532_ERROR_EXTENDEDFRAME + - PN532_ERROR_LENCHECKSUMMISMATCH + - PN532_ERROR_SPIREADYSTATUSTIMEOUT +*/ +/**************************************************************************/ +pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen) +{ + size_t t, i; + pn532_pcb_t *pn532 = pn532GetPCB(); + + // Check if we're busy + if (pn532->state == PN532_STATE_BUSY) + { + return PN532_ERROR_BUSY; + } + pn532->state = PN532_STATE_BUSY; + pn532->appError = PN532_APPERROR_NONE; + + // Wait for the response ready signal + t = 0; + while (pn532GetStatus() != PN532_SPI_READY) + { + if(t++>PN532_SPI_TIMEOUT) + { + PN532_DEBUG("Timeout waiting for READY status%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_SPIREADYSTATUSTIMEOUT; + } + systickDelay(1); + } + + PN532_SELECT; + systickDelay(1); + + pn532SPIWrite(PN532_SPI_DATAREAD); + + // Check preamble + pbtResponse[0] = pn532SPIRead(); + pbtResponse[1] = pn532SPIRead(); + pbtResponse[2] = pn532SPIRead(); + const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff }; + if (0 != (memcmp (pbtResponse, pn53x_preamble, 3))) + { + PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_PREAMBLEMISMATCH; + } + + // Check the frame type + pbtResponse[3] = pn532SPIRead(); + pbtResponse[4] = pn532SPIRead(); + pbtResponse[5] = pn532SPIRead(); + if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) + { + // Error frame + PN532_DEBUG("Application level error (%02d)%s", pbtResponse[5], CFG_PRINTF_NEWLINE); + // Set application error message ID + pn532->appError = pbtResponse[5]; + pn532->state = PN532_STATE_READY; + return PN532_ERROR_APPLEVELERROR; + } + else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) + { + // Extended frame + PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_EXTENDEDFRAME; + } + else + { + // Check checksum, unless this is a response to the wakeup command + if (pn532->lastCommand = PN532_COMMAND_SAMCONFIGURATION) + { + *pszRxLen = 6; + } + else + { + // Normal frame + if (256 != (pbtResponse[3] + pbtResponse[4])) + { + // TODO: Retry + PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE); + pn532PrintHex(pbtResponse, 6); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_LENCHECKSUMMISMATCH; + } + // Read payload + size_t szPayloadLen = pbtResponse[3] - 2; + for (i=0; istate = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sends the wakeup sequence to the PN532. +*/ +/**************************************************************************/ +pn532_error_t pn532Wakeup(void) +{ + size_t szLen; + byte_t abtWakeUp[] = { 0x01,0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 }; + // byte_t abtWakeUp[] = { 0x01,0x00,0x00,0xff,0x03,0xfd,0xd4,PN532_COMMAND_SAMCONFIGURATION,0x01,0x17,0x00 }; + + pn532_pcb_t *pn532 = pn532GetPCB(); + + PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE); + + PN532_SELECT; + systickDelay(2); + + // Transmit wakeup sequence + pn532SPIWriteArray(abtWakeUp, sizeof(abtWakeUp)); + systickDelay(100); + + // Register the last command that was sent + pn532->lastCommand = PN532_COMMAND_SAMCONFIGURATION; + + byte_t response[32]; + pn532ReadResponse(response, &szLen); + PN532_DESELECT; + + // Todo: Check for error ... currently throws a checksum error + // that isn't really an error + + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +#endif // #ifdef PN532_SPI diff --git a/drivers/sensors/pn532/pn532_drvr_uart.c b/drivers/sensors/pn532/pn532_drvr_uart.c new file mode 100644 index 0000000..abe029f --- /dev/null +++ b/drivers/sensors/pn532/pn532_drvr_uart.c @@ -0,0 +1,276 @@ +/**************************************************************************/ +/*! + @file pn532_drvr_uart.c +*/ +/**************************************************************************/ +#include + +#include "pn532.h" +#include "pn532_drvr.h" + +#ifdef PN532_UART + +#include "core/systick/systick.h" +#include "core/gpio/gpio.h" +#include "core/uart/uart.h" + +/**************************************************************************/ +/*! + @brief Initialises UART and configures the PN532 +*/ +/**************************************************************************/ +void pn532HWInit(void) +{ + PN532_DEBUG("Initialising UART (%d)%s", PN532_UART_BAUDRATE, CFG_PRINTF_NEWLINE); + uartInit(PN532_UART_BAUDRATE); + + // Set reset pin as output and reset device + gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output); + PN532_DEBUG("Resetting the PN532...\r\n"); + gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0); + systickDelay(400); + gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1); + + // Wait for the PN532 to finish booting + systickDelay(100); +} + +/**************************************************************************/ +/*! + @brief Builds a standard PN532 frame using the supplied data + + @param pbtFrame Pointer to the field that will hold the frame data + @param pszFrame Pointer to the field that will hold the frame length + @param pbtData Pointer to the data to insert in a frame + @param swData Length of the data to insert in bytes + + @note Possible error messages are: + + - PN532_ERROR_EXTENDEDFRAME +*/ +/**************************************************************************/ +pn532_error_t pn532BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData) +{ + if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN) + { + // Extended frames currently unsupported + return PN532_ERROR_EXTENDEDFRAME; + } + + // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1) + pbtFrame[3] = szData + 1; + // LCS - Packet length checksum + pbtFrame[4] = 256 - (szData + 1); + // TFI + pbtFrame[5] = 0xD4; + // DATA - Copy the PN53X command into the packet buffer + memcpy (pbtFrame + 6, pbtData, szData); + + // DCS - Calculate data payload checksum + byte_t btDCS = (256 - 0xD4); + size_t szPos; + for (szPos = 0; szPos < szData; szPos++) + { + btDCS -= pbtData[szPos]; + } + pbtFrame[6 + szData] = btDCS; + + // 0x00 - End of stream marker + pbtFrame[szData + 7] = 0x00; + + (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD; + + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sends the specified command to the PN532, automatically + creating an appropriate frame for it + + @param pdbData Pointer to the byte data to send + @param szData Length in bytes of the data to send + + @note Possible error messages are: + + - PN532_ERROR_BUSY + - PN532_ERROR_NOACK + - PN532_ERROR_INVALIDACK +*/ +/**************************************************************************/ +pn532_error_t pn532SendCommand(const byte_t * pbtData, const size_t szData) +{ + pn532_pcb_t *pn532 = pn532GetPCB(); + + // Check if we're busy + if (pn532->state == PN532_STATE_BUSY) + { + return PN532_ERROR_BUSY; + } + + // Flag the stack as busy + pn532->state = PN532_STATE_BUSY; + + // Every packet must start with "00 00 ff" + byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; + size_t szFrame = 0; + + // Build the frame + pn532BuildFrame (abtFrame, &szFrame, pbtData, szData); + + // Keep track of the last command that was sent + pn532->lastCommand = pbtData[0]; + + // Output the frame data for debugging if requested + PN532_DEBUG("Sending (%02d): ", szFrame); + pn532PrintHex(abtFrame, szFrame); + + // Send data to the PN532 + uartSend (abtFrame, szFrame); + + // Wait for ACK + byte_t abtRxBuf[6]; + uart_pcb_t *uart = uartGetPCB(); + systickDelay(10); // FIXME: How long should we wait for ACK? + if (uart->rxfifo.len < 6) + { + // Unable to read ACK + PN532_DEBUG ("Unable to read ACK%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NOACK; + } + + // Read ACK ... this will also remove it from the buffer + const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; + abtRxBuf[0] = uartRxBufferRead(); + abtRxBuf[1] = uartRxBufferRead(); + abtRxBuf[2] = uartRxBufferRead(); + abtRxBuf[3] = uartRxBufferRead(); + abtRxBuf[4] = uartRxBufferRead(); + abtRxBuf[5] = uartRxBufferRead(); + + // Make sure the received ACK matches the prototype + if (0 != (memcmp (abtRxBuf, abtAck, 6))) + { + PN532_DEBUG ("Invalid ACK: "); + pn532PrintHex(abtRxBuf, 6); + PN532_DEBUG("%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_INVALIDACK; + } + + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads a response from the PN532 + + @note Possible error message are: + + - PN532_ERROR_BUSY + - PN532_ERROR_RESPONSEBUFFEREMPTY + - PN532_ERROR_PREAMBLEMISMATCH + - PN532_ERROR_APPLEVELERROR + - PN532_ERROR_EXTENDEDFRAME + - PN532_ERROR_LENCHECKSUMMISMATCH +*/ +/**************************************************************************/ +pn532_error_t pn532ReadResponse(byte_t * pbtResponse, size_t * pszRxLen) +{ + pn532_pcb_t *pn532 = pn532GetPCB(); + + // Check if we're busy + if (pn532->state == PN532_STATE_BUSY) + { + return PN532_ERROR_BUSY; + } + + // Flag the stack as busy + pn532->state = PN532_STATE_BUSY; + + // Reset the app error flag + pn532->appError = PN532_APPERROR_NONE; + + // Read response from uart + if (!uartRxBufferReadArray(pbtResponse, pszRxLen)) + { + pn532->state = PN532_STATE_READY; + return PN532_ERROR_RESPONSEBUFFEREMPTY; + } + + // Display the raw response data for debugging if requested + PN532_DEBUG("Received (%02d): ", *pszRxLen); + pn532PrintHex(pbtResponse, *pszRxLen); + + // Check preamble + const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff }; + if (0 != (memcmp (pbtResponse, pn53x_preamble, 3))) + { + PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_PREAMBLEMISMATCH; + } + + // Check the frame type + if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) + { + // Error frame + PN532_DEBUG("Application level error (%02d)%s", pbtResponse[5], CFG_PRINTF_NEWLINE); + // Set application error message ID + pn532->appError = pbtResponse[5]; + pn532->state = PN532_STATE_READY; + return PN532_ERROR_APPLEVELERROR; + } + else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) + { + // Extended frame + PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_EXTENDEDFRAME; + } + else + { + // Normal frame + if (256 != (pbtResponse[3] + pbtResponse[4])) + { + // TODO: Retry + PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE); + pn532->state = PN532_STATE_READY; + return PN532_ERROR_LENCHECKSUMMISMATCH; + } + // size_t szPayloadLen = abtRx[3] - 2; + } + + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sends the wakeup sequence to the PN532. +*/ +/**************************************************************************/ +pn532_error_t pn532Wakeup(void) +{ + size_t szLen; + byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 }; + + pn532_pcb_t *pn532 = pn532GetPCB(); + + PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE); + uartSend(abtWakeUp,sizeof(abtWakeUp)); + systickDelay(100); + + byte_t response[32]; + pn532ReadResponse(response, &szLen); + + // Todo: Check for error ... currently throws a checksum error + // that isn't really an error + + pn532->state = PN532_STATE_READY; + return PN532_ERROR_NONE; +} + +#endif // #ifdef PN532_UART \ No newline at end of file diff --git a/drivers/sensors/pn532/pn532_mifare.c b/drivers/sensors/pn532/pn532_mifare.c new file mode 100644 index 0000000..1176833 --- /dev/null +++ b/drivers/sensors/pn532/pn532_mifare.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/*! + @file pn532_mifare.c +*/ +/**************************************************************************/ +#include + +#include "pn532.h" +#include "pn532_mifare.h" + +bool pn532MifareCmd(const pn532_mifare_cmd_t mc, const uint8_t ui8Block, pn532_mifare_param_t * pmp) +{ + byte_t abtRx[265]; + size_t szRx = sizeof(abtRx); + size_t szParamLen; + byte_t abtCmd[265]; + bool bEasyFraming; + + abtCmd[0] = mc; // The MIFARE Classic command + abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) + + switch (mc) { + // Read and store command have no parameter + case PN532_MIFARE_CMD_READ: + case PN532_MIFARE_CMD_STORE: + szParamLen = 0; + break; + + // Authenticate command + case PN532_MIFARE_CMD_AUTH_A: + case PN532_MIFARE_CMD_AUTH_B: + szParamLen = sizeof (pn532_mifare_param_auth_t); + break; + + // Data command + case PN532_MIFARE_CMD_WRITE: + szParamLen = sizeof (pn532_mifare_param_data_t); + break; + + // Value command + case PN532_MIFARE_CMD_DECREMENT: + case PN532_MIFARE_CMD_INCREMENT: + case PN532_MIFARE_CMD_TRANSFER: + szParamLen = sizeof (pn532_mifare_param_value_t); + break; + + // Please fix your code, you never should reach this statement + default: + return false; + break; + } + + // When available, copy the parameter bytes + if (szParamLen) + memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen); + +// bEasyFraming = pnd->bEasyFraming; +// if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) { +// nfc_perror (pnd, "nfc_configure"); +// return false; +// } +// +// // Fire the mifare command +// if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx)) { +// if (pnd->iLastError == EINVRXFRAM) { +// // "Invalid received frame" AKA EINVRXFRAM, usual means we are +// // authenticated on a sector but the requested MIFARE cmd (read, write) +// // is not permitted by current acces bytes; +// // So there is nothing to do here. +// } else { +// nfc_perror (pnd, "nfc_initiator_transceive_bytes"); +// } +// nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming); +// return false; +// } +// if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) { +// nfc_perror (pnd, "nfc_configure"); +// return false; +// } +// +// // When we have executed a read command, copy the received bytes into the param +// if (mc == MC_READ) { +// if (szRx == 16) { +// memcpy (pmp->mpd.abtData, abtRx, 16); +// } else { +// return false; +// } +// } + + // Command succesfully executed + return true; +} diff --git a/drivers/sensors/pn532/pn532_mifare.h b/drivers/sensors/pn532/pn532_mifare.h new file mode 100644 index 0000000..0ea8464 --- /dev/null +++ b/drivers/sensors/pn532/pn532_mifare.h @@ -0,0 +1,123 @@ +/**************************************************************************/ +/*! + @file pn532_mifare.h +*/ +/**************************************************************************/ + +#ifndef __PN532_MIFARE_H__ +#define __PN532_MIFARE_H__ + +#include "projectconfig.h" + +typedef enum pn532_mifare_cmd_e +{ + PN532_MIFARE_CMD_AUTH_A = 0x60, + PN532_MIFARE_CMD_AUTH_B = 0x61, + PN532_MIFARE_CMD_READ = 0x30, + PN532_MIFARE_CMD_WRITE = 0xA0, + PN532_MIFARE_CMD_TRANSFER = 0xB0, + PN532_MIFARE_CMD_DECREMENT = 0xC0, + PN532_MIFARE_CMD_INCREMENT = 0xC1, + PN532_MIFARE_CMD_STORE = 0xC2 +} +pn532_mifare_cmd_t; + +typedef struct +{ + byte_t abtKey[6]; + byte_t abtUid[4]; +} +pn532_mifare_param_auth_t; + +typedef struct +{ + byte_t abtData[16]; +} +pn532_mifare_param_data_t; + +typedef struct +{ + byte_t abtValue[4]; +} +pn532_mifare_param_value_t; + +typedef union +{ + pn532_mifare_param_auth_t mpa; + pn532_mifare_param_data_t mpd; + pn532_mifare_param_value_t mpv; +} +pn532_mifare_param_t; + +// MIFARE Classic +typedef struct +{ + byte_t abtUID[4]; + byte_t btBCC; + byte_t btUnknown; + byte_t abtATQA[2]; + byte_t abtUnknown[8]; +} +pn532_mifare_classic_block_manufacturer_t; + +typedef struct +{ + byte_t abtData[16]; +} +pn532_mifare_classic_block_data_t; + +typedef struct +{ + byte_t abtKeyA[6]; + byte_t abtAccessBits[4]; + byte_t abtKeyB[6]; +} +pn532_mifare_classic_block_trailer_t; + +typedef union +{ + pn532_mifare_classic_block_manufacturer_t mbm; + pn532_mifare_classic_block_data_t mbd; + pn532_mifare_classic_block_trailer_t mbt; +} +pn532_mifare_classic_block_t; + +typedef struct +{ + pn532_mifare_classic_block_t amb[256]; +} +pn532_mifare_classic_tag_t; + +// MIFARE Ultralight +typedef struct +{ + byte_t sn0[3]; + byte_t btBCC0; + byte_t sn1[4]; + byte_t btBCC1; + byte_t internal; + byte_t lock[2]; + byte_t otp[4]; +} +pn532_mifareul_block_manufacturer_t; + +typedef struct +{ + byte_t abtData[16]; +} +pn532_mifareul_block_data_t; + +typedef union +{ + pn532_mifareul_block_manufacturer_t mbm; + pn532_mifareul_block_data_t mbd; +} +pn532_mifareul_block_t; + +typedef struct +{ + pn532_mifareul_block_t amb[4]; +} +pn532_mifareul_tag_t; + +#endif diff --git a/drivers/sensors/tcs3414/tcs3414.c b/drivers/sensors/tcs3414/tcs3414.c new file mode 100644 index 0000000..2a81c71 --- /dev/null +++ b/drivers/sensors/tcs3414/tcs3414.c @@ -0,0 +1,260 @@ +/**************************************************************************/ +/*! + @file tcs3414.c + @author K. Townsend (microBuilder.eu) + Morten Hjerde (tcs3414CalculateCCT) + + @brief Drivers for the TAOS TCS3414 I2C RGB sensor + + @section DESCRIPTION + + The TAOS TCS3414 is a digital color/light sensor that can be used + to derive the color chromaticity and illuminance of ambient light + with 16-bit resolution. The device has an array of filtered + photo-diodes with 4 red, 4 green, 4 blue and 4 unfiltered + captors. The sensor has digital gain and prescalar support so that + the sensitivty of the device can be dynamically adjusted with a + 1,000,000:1 dynamic range. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "tcs3414.h" +#include "core/systick/systick.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +uint32_t i; + +static bool _tcs3414Initialised = false; + +/**************************************************************************/ +/*! + @brief Sends a single command byte over I2C +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414WriteCmd (uint8_t cmd) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 0; + I2CMasterBuffer[0] = TCS3414_ADDRESS; // I2C device address + I2CMasterBuffer[1] = cmd; // Command register + i2cEngine(); + return TCS3414_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Writes an 8 bit values over I2C +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414Write8 (uint8_t reg, uint32_t value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 3; + I2CReadLength = 0; + I2CMasterBuffer[0] = TCS3414_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + I2CMasterBuffer[2] = (value & 0xFF); // Value to write + i2cEngine(); + return TCS3414_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Reads a 16 bit values over I2C +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414Read16(uint8_t reg, uint16_t *value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 2; + I2CMasterBuffer[0] = TCS3414_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + // Append address w/read bit + I2CMasterBuffer[2] = TCS3414_ADDRESS | TCS3414_READBIT; + i2cEngine(); + + // Shift values to create properly formed integer (low byte first) + *value = (I2CSlaveBuffer[0] | (I2CSlaveBuffer[1] << 8)); + + return TCS3414_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Initialises the I2C block +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414Init(void) +{ + // Initialise I2C + if (i2cInit(I2CMASTER) == false) + { + return TCS3414_ERROR_I2CINIT; /* Fatal error */ + } + + _tcs3414Initialised = true; + + // Note: by default, the device is in power down mode on bootup + + return TCS3414_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Sets the gain and prescalar to control sensitivty +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414SetSensitivity(tcs3414Gain_t gain, tcs3414Prescalar_t prescalar) +{ + if (!_tcs3414Initialised) tcs3414Init(); + + tcs3414Error_e error = TCS3414_ERROR_OK; + + // Enable the device by setting the control bit to 0x03 (power + ADC on) + error = tcs3414Write8(TCS3414_COMMAND_BIT | TCS3414_REGISTER_CONTROL, TCS3414_CONTROL_POWERON); + if (error) return error; + + // Set the gani and prescalar values using the GAIN register + error = tcs3414Write8(TCS3414_COMMAND_BIT | TCS3414_REGISTER_GAIN, gain | prescalar); + if (error) return error; + + // Turn the device off to save power + error = tcs3414Write8(TCS3414_COMMAND_BIT | TCS3414_REGISTER_CONTROL, TCS3414_CONTROL_POWEROFF); + if (error) return error; + + return error; +} + +/**************************************************************************/ +/*! + @brief Reads the RGB and clear luminosity from the TCS3414 +*/ +/**************************************************************************/ +tcs3414Error_e tcs3414GetRGBL(uint16_t *red, uint16_t *green, uint16_t *blue, uint16_t *clear) +{ + if (!_tcs3414Initialised) tcs3414Init(); + + tcs3414Error_e error = TCS3414_ERROR_OK; + + // Enable the device by setting the control bit to 0x03 (power + ADC on) + error = tcs3414Write8(TCS3414_COMMAND_BIT | TCS3414_REGISTER_CONTROL, TCS3414_CONTROL_POWERON); + if (error) return error; + + // Wait >12ms for ADC to complete + systickDelay(13); + + // Reads two byte red value + error = tcs3414Read16(TCS3414_COMMAND_BIT | TCS3414_WORD_BIT | TCS3414_REGISTER_REDLOW, red); + if (error) return error; + + // Reads two byte green value + error = tcs3414Read16(TCS3414_COMMAND_BIT | TCS3414_WORD_BIT | TCS3414_REGISTER_GREENLOW, green); + if (error) return error; + + // Reads two byte blue value + error = tcs3414Read16(TCS3414_COMMAND_BIT | TCS3414_WORD_BIT | TCS3414_REGISTER_BLUELOW, blue); + if (error) return error; + + // Reads two byte clear value + error = tcs3414Read16(TCS3414_COMMAND_BIT | TCS3414_WORD_BIT | TCS3414_REGISTER_CLEARLOW, clear); + if (error) return error; + + // Turn the device off to save power + error = tcs3414Write8(TCS3414_COMMAND_BIT | TCS3414_REGISTER_CONTROL, TCS3414_CONTROL_POWEROFF); + if (error) return error; + + return error; +} + +/**************************************************************************/ +/*! + @brief Reads the RGB values from the TCS3414 color sensor and + calculates CCT (Correlated Color Temperature) + + @return The Correlated Color Temperature in Kelvin +*/ +/**************************************************************************/ +uint32_t tcs3414CalculateCCT (uint16_t red, uint16_t green, uint16_t blue) +{ + volatile float R; + volatile float G; + volatile float B; + volatile float X; + volatile float Y; + volatile float Z; + volatile float x; + volatile float y; + volatile float n; + volatile float CCT; + + // Convert RGB values to a 0-100 scale + R = (((float) red) / 65536) * 100; + G = (((float) green) / 65536) * 100; + B = (((float) blue)/ 65536) * 100; + + //do matrix transformation + X = (-0.14282 * R) + (1.54924 * G) + (-0.95641 * B); + Y = (-0.32466 * R) + (1.57837 * G) + (-0.73191 * B); + Z = (-0.68202 * R) + (0.77073 * G) + (0.56332 * B); + + //calc chromaticity coordinates + x = (X)/(X + Y + Z); + y = (Y)/(X + Y + Z); + + //use McCamy’s formula to get CCT: + n = (x - 0.3320) / (0.1858 - y); + CCT = (449 * n * n * n); // we don't have pow + CCT += (3525 * n * n); + CCT += (6823.3 * n); + CCT += 5520.33; + + return ((uint32_t) CCT); +} diff --git a/drivers/sensors/tcs3414/tcs3414.h b/drivers/sensors/tcs3414/tcs3414.h new file mode 100644 index 0000000..146c870 --- /dev/null +++ b/drivers/sensors/tcs3414/tcs3414.h @@ -0,0 +1,130 @@ +/**************************************************************************/ +/*! + @file tcs3414.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _TCS3414_H_ +#define _TCS3414_H_ + +#include "projectconfig.h" +#include "core/i2c/i2c.h" + +#define TCS3414_ADDRESS (0x72) // 0111001 shifted left 1 bit = 0x72 (ADDR = GND or floating) +#define TCS3414_READBIT (0x01) + +#define TCS3414_COMMAND_BIT (0x80) // Must be 1 +#define TCS3414_WORD_BIT (0x20) // 1 = read/write word (rather than byte) + +#define TCS3414_REGISTER_CONTROL (0x00) +#define TCS3414_REGISTER_TIMING (0x01) +#define TCS3414_REGISTER_INTERRUPT (0x02) +#define TCS3414_REGISTER_INTSOURCE (0x03) +#define TCS3414_REGISTER_PARTNO_REVID (0x04) +#define TCS3414_REGISTER_GAIN (0x07) +#define TCS3414_REGISTER_LOWTHRESHOLD_LOWBYTE (0x08) +#define TCS3414_REGISTER_LOWTHRESHOLD_HIGHBYTE (0x09) +#define TCS3414_REGISTER_HIGHTHRESHOLD_LOWBYTE (0x0A) +#define TCS3414_REGISTER_HIGHTHRESHOLD_HIGHBYTE (0x0B) +#define TCS3414_REGISTER_GREENLOW (0x10) +#define TCS3414_REGISTER_GREENHIGH (0x11) +#define TCS3414_REGISTER_REDLOW (0x12) +#define TCS3414_REGISTER_REDHIGH (0x13) +#define TCS3414_REGISTER_BLUELOW (0x14) +#define TCS3414_REGISTER_BLUEHIGH (0x15) +#define TCS3414_REGISTER_CLEARLOW (0x16) +#define TCS3414_REGISTER_CLEARHIGH (0x17) + +#define TCS3414_CONTROL_POWERON (0x03) +#define TCS3414_CONTROL_POWEROFF (0x00) + +#define TCS3414_GAIN_GAINMASK (0x30) +#define TCS3414_GAIN_PRESCALARMASK (0x07) + +/**************************************************************************/ +/*! + The Gain setting (bit [5:4] in the GAIN register) multiplies the output + by the specified amount, allowing you to adjust it's sensitivity and + dynamic range. +*/ +/**************************************************************************/ +typedef enum +{ + tcs3414Gain_1 = 0x00, + tcs3414Gain_4 = 0x10, + tcs3414Gain_16 = 0x20, + tcs3414Gain_64 = 0x30 +} +tcs3414Gain_t; + +/**************************************************************************/ +/*! + The Prescalar (bits [2:0] in the GAIN register) divides down the + output by the specified amount, allowing you to adjust it's + sensitivity and dynamic range. +*/ +/**************************************************************************/ +typedef enum +{ + tcs3414Prescalar_1 = 0x00, + tcs3414Prescalar_2 = 0x01, + tcs3414Prescalar_4 = 0x02, + tcs3414Prescalar_8 = 0x03, + tcs3414Prescalar_16 = 0x04, + tcs3414Prescalar_32 = 0x05, + tcs3414Prescalar_64 = 0x06 +} +tcs3414Prescalar_t; + +/**************************************************************************/ +/*! + Possible I2C error messages +*/ +/**************************************************************************/ +typedef enum +{ + TCS3414_ERROR_OK = 0, // Everything executed normally + TCS3414_ERROR_I2CINIT, // Unable to initialise I2C + TCS3414_ERROR_I2CBUSY, // I2C already in use + TCS3414_ERROR_LAST +} +tcs3414Error_e; + +tcs3414Error_e tcs3414Init(void); +tcs3414Error_e tcs3414SetSensitivity(tcs3414Gain_t gain, tcs3414Prescalar_t prescalar); +tcs3414Error_e tcs3414GetRGBL (uint16_t *red, uint16_t *green, uint16_t *blue, uint16_t *clear); +uint32_t tcs3414CalculateCCT (uint16_t red, uint16_t green, uint16_t blue); + +#endif + + diff --git a/drivers/sensors/tsl2561/tsl2561.c b/drivers/sensors/tsl2561/tsl2561.c new file mode 100644 index 0000000..79027b5 --- /dev/null +++ b/drivers/sensors/tsl2561/tsl2561.c @@ -0,0 +1,364 @@ +/**************************************************************************/ +/*! + @file tsl2561.c + @author K. Townsend (microBuilder.eu) + + @brief Drivers for the TAOS TSL2561 I2C digital luminosity sensor + + @section DESCRIPTION + + The TSL2561 is a 16-bit digital luminosity sensor the approximates + the human eye's response to light. It contains one broadband + photodiode that measures visible plus infrared light (channel 0) + and one infrared photodiode (channel 1). + + @section EXAMPLE + + @code + #include "drivers/sensors/tsl2561/tsl2561.h" + ... + uint16_t broadband, ir; + uint32_t lux; + + // Initialise luminosity sensor + tsl2561Init(); + + // Optional ... default setting is 400ms with no gain + // Set timing to 101ms with no gain + tsl2561SetTiming(TSL2561_INTEGRATIONTIME_101MS, TSL2561_GAIN_0X); + + // Check luminosity level and calculate lux + tsl2561GetLuminosity(&broadband, &ir); + lux = tsl2561CalculateLux(broadband, ir); + printf("Broadband: %u, IR: %u, Lux: %d %s", broadband, ir, lux, CFG_PRINTF_NEWLINE); + + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "tsl2561.h" +#include "core/systick/systick.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; +extern volatile uint32_t I2CReadLength, I2CWriteLength; + +uint32_t i; + +static bool _tsl2561Initialised = false; +static tsl2561IntegrationTime_t _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_402MS; +static tsl2561Gain_t _tsl2561Gain = TSL2561_GAIN_0X; + +/**************************************************************************/ +/*! + @brief Sends a single command byte over I2C +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561WriteCmd (uint8_t cmd) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 0; + I2CMasterBuffer[0] = TSL2561_ADDRESS; // I2C device address + I2CMasterBuffer[1] = cmd; // Command register + i2cEngine(); + return TSL2561_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Writes an 8 bit values over I2C +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561Write8 (uint8_t reg, uint32_t value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 3; + I2CReadLength = 0; + I2CMasterBuffer[0] = TSL2561_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + I2CMasterBuffer[2] = (value & 0xFF); // Value to write + i2cEngine(); + return TSL2561_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Reads a 16 bit values over I2C +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561Read16(uint8_t reg, uint16_t *value) +{ + // Clear write buffers + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 2; + I2CMasterBuffer[0] = TSL2561_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + // Append address w/read bit + I2CMasterBuffer[2] = TSL2561_ADDRESS | TSL2561_READBIT; + i2cEngine(); + + // Shift values to create properly formed integer (low byte first) + *value = (I2CSlaveBuffer[0] | (I2CSlaveBuffer[1] << 8)); + + return TSL2561_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Enables the device +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561Enable(void) +{ + if (!_tsl2561Initialised) tsl2561Init(); + + // Enable the device by setting the control bit to 0x03 + return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON); +} + +/**************************************************************************/ +/*! + @brief Disables the device (putting it in lower power sleep mode) +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561Disable(void) +{ + if (!_tsl2561Initialised) tsl2561Init(); + + // Turn the device off to save power + return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF); +} + +/**************************************************************************/ +/*! + @brief Initialises the I2C block +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561Init(void) +{ + // Initialise I2C + if (i2cInit(I2CMASTER) == false) + { + return TSL2561_ERROR_I2CINIT; /* Fatal error */ + } + + _tsl2561Initialised = true; + + // Set default integration time and gain + tsl2561SetTiming(_tsl2561IntegrationTime, _tsl2561Gain); + + // Note: by default, the device is in power down mode on bootup + + return TSL2561_ERROR_OK; +} + +/**************************************************************************/ +/*! + @brief Sets the integration time and gain (controls sensitivity) +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561SetTiming(tsl2561IntegrationTime_t integration, tsl2561Gain_t gain) +{ + if (!_tsl2561Initialised) tsl2561Init(); + + tsl2561Error_t error = TSL2561_ERROR_OK; + + // Enable the device by setting the control bit to 0x03 + error = tsl2561Enable(); + if (error) return error; + + // Turn the device off to save power + error = tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, integration | gain); + if (error) return error; + + // Update value placeholders + _tsl2561IntegrationTime = integration; + _tsl2561Gain = gain; + + // Turn the device off to save power + error = tsl2561Disable(); + if (error) return error; + + return error; +} + +/**************************************************************************/ +/*! + @brief Reads the luminosity on both channels from the TSL2561 +*/ +/**************************************************************************/ +tsl2561Error_t tsl2561GetLuminosity (uint16_t *broadband, uint16_t *ir) +{ + if (!_tsl2561Initialised) tsl2561Init(); + + tsl2561Error_t error = TSL2561_ERROR_OK; + + // Enable the device by setting the control bit to 0x03 + error = tsl2561Enable(); + if (error) return error; + + // Wait x ms for ADC to complete + switch (_tsl2561IntegrationTime) + { + case TSL2561_INTEGRATIONTIME_13MS: + systickDelay(14); + break; + case TSL2561_INTEGRATIONTIME_101MS: + systickDelay(102); + break; + default: + systickDelay(400); + break; + } + + // Reads two byte value from channel 0 (visible + infrared) + error = tsl2561Read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW, broadband); + if (error) return error; + + // Reads two byte value from channel 1 (infrared) + error = tsl2561Read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW, ir); + if (error) return error; + + // Turn the device off to save power + error = tsl2561Disable(); + if (error) return error; + + return error; +} + +/**************************************************************************/ +/*! + @brief Calculates LUX from the supplied ch0 (broadband) and ch1 + (IR) readings +*/ +/**************************************************************************/ +uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1) +{ + unsigned long chScale; + unsigned long channel1; + unsigned long channel0; + + switch (_tsl2561IntegrationTime) + { + case TSL2561_INTEGRATIONTIME_13MS: + chScale = TSL2561_LUX_CHSCALE_TINT0; + break; + case TSL2561_INTEGRATIONTIME_101MS: + chScale = TSL2561_LUX_CHSCALE_TINT1; + break; + default: // No scaling ... integration time = 402ms + chScale = (1 << TSL2561_LUX_CHSCALE); + break; + } + + // Scale for gain (1x or 16x) + if (!_tsl2561Gain) chScale = chScale << 4; + + // scale the channel values + channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE; + channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE; + + // find the ratio of the channel values (Channel1/Channel0) + unsigned long ratio1 = 0; + if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0; + + // round the ratio value + unsigned long ratio = (ratio1 + 1) >> 1; + + unsigned int b, m; + +#ifdef TSL2561_PACKAGE_CS + if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) + {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;} + else if (ratio <= TSL2561_LUX_K2C) + {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;} + else if (ratio <= TSL2561_LUX_K3C) + {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;} + else if (ratio <= TSL2561_LUX_K4C) + {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;} + else if (ratio <= TSL2561_LUX_K5C) + {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;} + else if (ratio <= TSL2561_LUX_K6C) + {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;} + else if (ratio <= TSL2561_LUX_K7C) + {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;} + else if (ratio > TSL2561_LUX_K8C) + {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;} +#else + if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) + {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;} + else if (ratio <= TSL2561_LUX_K2T) + {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;} + else if (ratio <= TSL2561_LUX_K3T) + {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;} + else if (ratio <= TSL2561_LUX_K4T) + {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;} + else if (ratio <= TSL2561_LUX_K5T) + {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;} + else if (ratio <= TSL2561_LUX_K6T) + {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;} + else if (ratio <= TSL2561_LUX_K7T) + {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;} + else if (ratio > TSL2561_LUX_K8T) + {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;} +#endif + + unsigned long temp; + temp = ((channel0 * b) - (channel1 * m)); + + // do not allow negative lux value + if (temp < 0) temp = 0; + + // round lsb (2^(LUX_SCALE-1)) + temp += (1 << (TSL2561_LUX_LUXSCALE-1)); + + // strip off fractional portion + uint32_t lux = temp >> TSL2561_LUX_LUXSCALE; + + // Signal I2C had no errors + return lux; +} diff --git a/drivers/sensors/tsl2561/tsl2561.h b/drivers/sensors/tsl2561/tsl2561.h new file mode 100644 index 0000000..9cad43a --- /dev/null +++ b/drivers/sensors/tsl2561/tsl2561.h @@ -0,0 +1,163 @@ +/**************************************************************************/ +/*! + @file tsl2561.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _TSL2561_H_ +#define _TSL2561_H_ + +#include "projectconfig.h" +#include "core/i2c/i2c.h" + +#define TSL2561_PACKAGE_CS // Lux calculations differ slightly for CS package +// #define TSL2561_PACKAGE_T_FN_CL + +#define TSL2561_ADDRESS (0x72) // 0111001 shifted left 1 bit = 0x72 (ADDR = GND or floating) +#define TSL2561_READBIT (0x01) + +#define TSL2561_COMMAND_BIT (0x80) // Must be 1 +#define TSL2561_CLEAR_BIT (0x40) // Clears any pending interrupt (write 1 to clear) +#define TSL2561_WORD_BIT (0x20) // 1 = read/write word (rather than byte) +#define TSL2561_BLOCK_BIT (0x10) // 1 = using block read/write + +#define TSL2561_CONTROL_POWERON (0x03) +#define TSL2561_CONTROL_POWEROFF (0x00) + +#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14 +#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9 +#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10 +#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE +#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE + +// T, FN and CL package values +#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE +#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE +#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE +#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE +#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE +#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE +#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE +#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE +#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE +#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE +#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE +#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE +#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE +#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE +#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE +#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE +#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE +#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE +#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE +#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE +#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE +#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE + +// CS package values +#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE +#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE +#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE +#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE +#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE +#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE +#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE +#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE +#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE +#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE +#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE +#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE +#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE +#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE +#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE +#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE +#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE +#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE +#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE +#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE +#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE +#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE + +enum +{ + TSL2561_REGISTER_CONTROL = 0x00, + TSL2561_REGISTER_TIMING = 0x01, + TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02, + TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, + TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04, + TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, + TSL2561_REGISTER_INTERRUPT = 0x06, + TSL2561_REGISTER_CRC = 0x08, + TSL2561_REGISTER_ID = 0x0A, + TSL2561_REGISTER_CHAN0_LOW = 0x0C, + TSL2561_REGISTER_CHAN0_HIGH = 0x0D, + TSL2561_REGISTER_CHAN1_LOW = 0x0E, + TSL2561_REGISTER_CHAN1_HIGH = 0x0F +}; + +typedef enum +{ + TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7ms + TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms + TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms +} +tsl2561IntegrationTime_t; + +typedef enum +{ + TSL2561_GAIN_0X = 0x00, // No gain + TSL2561_GAIN_16X = 0x10, // 16x gain +} +tsl2561Gain_t; + +typedef enum +{ + TSL2561_ERROR_OK = 0, // Everything executed normally + TSL2561_ERROR_I2CINIT, // Unable to initialise I2C + TSL2561_ERROR_I2CBUSY, // I2C already in use + TSL2561_ERROR_LAST +} +tsl2561Error_t; + +tsl2561Error_t tsl2561Init(void); +tsl2561Error_t tsl2561SetTiming(tsl2561IntegrationTime_t integration, tsl2561Gain_t gain); +tsl2561Error_t tsl2561GetLuminosity (uint16_t *broadband, uint16_t *ir); +uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1); + +#endif + + diff --git a/lpc134x-vcom.inf b/lpc134x-vcom.inf new file mode 100644 index 0000000..c5a5384 --- /dev/null +++ b/lpc134x-vcom.inf @@ -0,0 +1,65 @@ +; +; Keil - An ARM Company Comunication Device Class driver installation file +; (C)2007 Copyright +; + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%Keil% +;LayoutFile=layout.inf +DriverVer=01/06/07 + +[Manufacturer] +%Keil%=DeviceList + +[DestinationDirs] +DefaultDestDir=12 + +[SourceDisksFiles] + +[SourceDisksNames] + +[DeviceList] +%DESCRIPTION%=LPC134xUSB, USB\VID_239A&PID_1002 + +;------------------------------------------------------------------------------ +; Windows 2000/XP Sections +;------------------------------------------------------------------------------ + +[LPC134xUSB.nt] +include=mdmcpq.inf +CopyFiles=DriverCopyFiles +AddReg=LPC134xUSB.nt.AddReg + +[DriverCopyFiles] +usbser.sys,,,0x20 + +[LPC134xUSB.nt.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[LPC134xUSB.nt.Services] +include=mdmcpq.inf +AddService=usbser, 0x00000002, DriverService + + +[LPC134xUSB.nt.HW] +include=mdmcpq.inf + +[DriverService] +DisplayName=%DESCRIPTION% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\usbser.sys + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ + +[Strings] +NXP="NXP - Founded by Philips" +DESCRIPTION="LPC134x USB VCom Port" diff --git a/lpc134x.h b/lpc134x.h new file mode 100644 index 0000000..e69af30 --- /dev/null +++ b/lpc134x.h @@ -0,0 +1,3534 @@ +/**************************************************************************/ +/*! + @file lpc134x.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section DESCRIPTION + + LPC1343 header file, based on V0.10 of the LPC1343 User Manual. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _LPC134X_H_ +#define _LPC134X_H_ + +#include "sysdefs.h" +#include "projectconfig.h" + +/*############################################################################## +## System Control Block +##############################################################################*/ + +#define SCB_BASE_ADDRESS (*(pREG32 (0x40048000))) // System control block base address + +#define SCB_MEMREMAP (*(pREG32 (0x40048000))) // System memory remap +#define SCB_PRESETCTRL (*(pREG32 (0x40048004))) // Peripheral reset control +#define SCB_PLLCTRL (*(pREG32 (0x40048008))) // System PLL control +#define SCB_PLLSTAT (*(pREG32 (0x4004800C))) // System PLL status +#define SCB_USBPLLCTRL (*(pREG32 (0x40048010))) // USB PLL control +#define SCB_USBPLLSTAT (*(pREG32 (0x40048014))) // USB PLL status +#define SCB_SYSOSCCTRL (*(pREG32 (0x40048020))) // System oscillator control +#define SCB_WDTOSCCTRL (*(pREG32 (0x40048024))) // Watchdog oscillator control +#define SCB_IRCCTRL (*(pREG32 (0x40048028))) // IRC control +#define SCB_RESETSTAT (*(pREG32 (0x40048030))) // System reset status register +#define SCB_PLLCLKSEL (*(pREG32 (0x40048040))) // System PLL clock source select +#define SCB_PLLCLKUEN (*(pREG32 (0x40048044))) // System PLL clock source update enable +#define SCB_USBPLLCLKSEL (*(pREG32 (0x40048048))) // USB PLL clock source select +#define SCB_USBPLLCLKUEN (*(pREG32 (0x4004804C))) // USB PLL clock source update enable +#define SCB_MAINCLKSEL (*(pREG32 (0x40048070))) // Main clock source select +#define SCB_MAINCLKUEN (*(pREG32 (0x40048074))) // Main clock source update enable +#define SCB_SYSAHBCLKDIV (*(pREG32 (0x40048078))) // System AHB clock divider +#define SCB_SYSAHBCLKCTRL (*(pREG32 (0x40048080))) // System AHB clock control +#define SCB_SSP0CLKDIV (*(pREG32 (0x40048094))) // SSP0 clock divider +#define SCB_UARTCLKDIV (*(pREG32 (0x40048098))) // UART clock divider +#define SCB_SYSTICKCLKDIV (*(pREG32 (0x400480B0))) // System tick clock divider +#define SCB_USBCLKSEL (*(pREG32 (0x400480C0))) // USB clock source select +#define SCB_USBCLKUEN (*(pREG32 (0x400480C4))) // USB clock source update enable +#define SCB_USBCLKDIV (*(pREG32 (0x400480C8))) // USB clock divider +#define SCB_WDTCLKSEL (*(pREG32 (0x400480D0))) // Watchdog clock source select +#define SCB_WDTCLKUEN (*(pREG32 (0x400480D4))) // Watchdog clock source update enable +#define SCB_WDTCLKDIV (*(pREG32 (0x400480D8))) // Watchdog clock divider +#define SCB_CLKOUTCLKSEL (*(pREG32 (0x400480E0))) // CLKOUT clock source select +#define SCB_CLKOUTCLKUEN (*(pREG32 (0x400480E4))) // CLKOUT clock source update enable +#define SCB_CLKOUTCLKDIV (*(pREG32 (0x400480E8))) // CLKOUT clock divider +#define SCB_PIOPORCAP0 (*(pREG32 (0x40048100))) // POR captured PIO status 0 +#define SCB_PIOPORCAP1 (*(pREG32 (0x40048104))) // POR captured PIO status 1 +#define SCB_BODCTRL (*(pREG32 (0x40048150))) // Brown-out detector control +#define SCB_SYSTICKCCAL (*(pREG32 (0x40048158))) // System tick counter calibration +#define SCB_STARTAPRP0 (*(pREG32 (0x40048200))) // Start logic edge control register 0; bottom 32 interrupts +#define SCB_STARTERP0 (*(pREG32 (0x40048204))) // Start logic signal enable register 0; bottom 32 interrupts +#define SCB_STARTRSRP0CLR (*(pREG32 (0x40048208))) // Start logic reset register 0; bottom 32 interrupts +#define SCB_STARTSRP0 (*(pREG32 (0x4004820C))) // Start logic status register 0; bottom 32 interrupts +#define SCB_STARTAPRP1 (*(pREG32 (0x40048210))) // Start logic edge control register 1; top 8 interrupts +#define SCB_STARTERP1 (*(pREG32 (0x40048214))) // Start logic signal enable register 1; top 8 interrupts +#define SCB_STARTRSRP1CLR (*(pREG32 (0x40048218))) // Start logic reset register 1; top 8 interrupts +#define SCB_STARTSRP1 (*(pREG32 (0x4004821C))) // Start logic status register 1; top 8 interrupts +#define SCB_PDSLEEPCFG (*(pREG32 (0x40048230))) // Power-down states in Deep-sleep mode +#define SCB_PDAWAKECFG (*(pREG32 (0x40048234))) // Power-down states after wake-up from Deep-sleep mode +#define SCB_PDRUNCFG (*(pREG32 (0x40048238))) // Power-down configuration register +#define SCB_DEVICEID (*(pREG32 (0x400483F4))) // Device ID +#define SCB_MMFAR (*(pREG32 (0xE000ED34))) // Memory Manage Address Register (MMAR) +#define SCB_BFAR (*(pREG32 (0xE000ED38))) // Bus Fault Manage Address Register (BFAR) +#define SCB_DEMCR (*(pREG32 (0xE000EDFC))) + +/* CPU ID Base Register */ +#define SCB_CPUID (*(pREG32 (0xE000ED00))) +#define SCB_CPUID_REVISION_MASK ((unsigned int) 0x0000000F) // Revision Code +#define SCB_CPUID_PARTNO_MASK ((unsigned int) 0x0000FFF0) // Part Number +#define SCB_CPUID_CONSTANT_MASK ((unsigned int) 0x000F0000) // Constant +#define SCB_CPUID_VARIANT_MASK ((unsigned int) 0x00F00000) // Variant +#define SCB_CPUID_IMPLEMENTER_MASK ((unsigned int) 0xFF000000) // Implementer + +/* System Control Register */ + +#define SCB_SCR (*(pREG32 (0xE000ED10))) +#define SCB_SCR_SLEEPONEXIT_MASK ((unsigned int) 0x00000002) // Enable sleep on exit +#define SCB_SCR_SLEEPONEXIT ((unsigned int) 0x00000002) +#define SCB_SCR_SLEEPDEEP_MASK ((unsigned int) 0x00000004) +#define SCB_SCR_SLEEPDEEP ((unsigned int) 0x00000004) // Enable deep sleep +#define SCB_SCR_SEVONPEND_MASK ((unsigned int) 0x00000010) // Wake up from WFE is new int is pended regardless of priority +#define SCB_SCR_SEVONPEND ((unsigned int) 0x00000010) + +/* Application Interrupt and Reset Control Register */ + +#define SCB_AIRCR (*(pREG32 (0xE000ED0C))) +#define SCB_AIRCR_VECTKEY_VALUE ((unsigned int) 0x05FA0000) // Vect key needs to be set to 05FA for reset to work +#define SCB_AIRCR_VECTKEY_MASK ((unsigned int) 0xFFFF0000) +#define SCB_AIRCR_ENDIANESS ((unsigned int) 0x00008000) // Read Endianness (1=Big, 0=Little) +#define SCB_AIRCR_ENDIANESS_MASK ((unsigned int) 0x00008000) +#define SCB_AIRCR_PRIGROUP ((unsigned int) 0x00000700) +#define SCB_AIRCR_PRIGROUP_MASK ((unsigned int) 0x00000700) +#define SCB_AIRCR_SYSRESETREQ ((unsigned int) 0x00000004) // Request system reset +#define SCB_AIRCR_SYSRESETREQ_MASK ((unsigned int) 0x00000004) +#define SCB_AIRCR_VECTCLRACTIVE ((unsigned int) 0x00000002) // Used to prevent accidental reset +#define SCB_AIRCR_VECTCLRACTIVE_MASK ((unsigned int) 0x00000002) +#define SCB_AIRCR_VECTRESET ((unsigned int) 0x00000001) +#define SCB_AIRCR_VECTRESET_MASK ((unsigned int) 0x00000001) + +/* Memory Management Fault Status Register */ + +#define SCB_MMFSR (*(pREG32 (0xE000ED28))) +#define SCB_MMFSR_IACCVIOL_MASK ((unsigned int) 0x00000001) // Instruction access violation +#define SCB_MMFSR_IACCVIOL ((unsigned int) 0x00000001) +#define SCB_MMFSR_DACCVIOL_MASK ((unsigned int) 0x00000002) // Data access violation +#define SCB_MMFSR_DACCVIOL ((unsigned int) 0x00000002) +#define SCB_MMFSR_MUNSTKERR_MASK ((unsigned int) 0x00000008) // Unstacking error +#define SCB_MMFSR_MUNSTKERR ((unsigned int) 0x00000008) +#define SCB_MMFSR_MSTKERR_MASK ((unsigned int) 0x00000010) // Stacking error +#define SCB_MMFSR_MSTKERR ((unsigned int) 0x00000010) +#define SCB_MMFSR_MMARVALID_MASK ((unsigned int) 0x00000080) // Indicates MMAR is valid +#define SCB_MMFSR_MMARVALID ((unsigned int) 0x00000080) + +/* Bus Fault Status Register */ + +#define SCB_BFSR (*(pREG32 (0xE000ED29))) +#define SCB_BFSR_IBUSERR_MASK ((unsigned int) 0x00000001) // Instruction access violation +#define SCB_BFSR_IBUSERR ((unsigned int) 0x00000001) +#define SCB_BFSR_PRECISERR_MASK ((unsigned int) 0x00000002) // Precise data access violation +#define SCB_BFSR_PRECISERR ((unsigned int) 0x00000002) +#define SCB_BFSR_IMPRECISERR_MASK ((unsigned int) 0x00000004) // Imprecise data access violation +#define SCB_BFSR_IMPRECISERR ((unsigned int) 0x00000004) +#define SCB_BFSR_UNSTKERR_MASK ((unsigned int) 0x00000008) // Unstacking error +#define SCB_BFSR_UNSTKERR ((unsigned int) 0x00000008) +#define SCB_BFSR_STKERR_MASK ((unsigned int) 0x00000010) // Stacking error +#define SCB_BFSR_STKERR ((unsigned int) 0x00000010) +#define SCB_BFSR_BFARVALID_MASK ((unsigned int) 0x00000080) // Indicates BFAR is valid +#define SCB_BFSR_BFARVALID ((unsigned int) 0x00000080) + +/* Usage Fault Status Register */ + +#define SCB_UFSR (*(pREG32 (0xE000ED2A))) +#define SCB_UFSR_UNDEFINSTR_MASK ((unsigned int) 0x00000001) // Attempt to execute an undefined instruction +#define SCB_UFSR_UNDEFINSTR ((unsigned int) 0x00000001) +#define SCB_UFSR_INVSTATE_MASK ((unsigned int) 0x00000002) // Attempt to switch to invalid state (i.e. ARM) +#define SCB_UFSR_INVSTATE ((unsigned int) 0x00000002) +#define SCB_UFSR_INVPC_MASK ((unsigned int) 0x00000004) // Attempt to do exception with bad value in EXC_RETURN number +#define SCB_UFSR_INVPC ((unsigned int) 0x00000004) +#define SCB_UFSR_NOCP_MASK ((unsigned int) 0x00000008) // Attempt to execute a coprocessor instruction +#define SCB_UFSR_NOCP ((unsigned int) 0x00000008) +#define SCB_UFSR_UNALIGNED_MASK ((unsigned int) 0x00000100) // Unaligned access +#define SCB_UFSR_UNALIGNED ((unsigned int) 0x00000100) +#define SCB_UFSR_DIVBYZERO_MASK ((unsigned int) 0x00000200) // Divide by zero +#define SCB_UFSR_DIVBYZERO ((unsigned int) 0x00000200) + +/* Hard Fault Status Register */ + +#define SCB_HFSR (*(pREG32 (0xE000ED2C))) +#define SCB_HFSR_VECTTBL_MASK ((unsigned int) 0x00000002) // Hard fault caused by failed vector fetch +#define SCB_HFSR_VECTTBL ((unsigned int) 0x00000002) +#define SCB_HFSR_FORCED_MASK ((unsigned int) 0x40000000) // Hard fault taken because of bus/mem man/usage fault +#define SCB_HFSR_FORCED ((unsigned int) 0x40000000) +#define SCB_HFSR_DEBUGEVT_MASK ((unsigned int) 0x80000000) // Hard fault triggered by debug event +#define SCB_HFSR_DEBUGEVT ((unsigned int) 0x80000000) + +/* Debug Fault Status Register */ + +#define SCB_DFSR (*(pREG32 (0xE000ED30))) +#define SCB_DFSR_HALTED_MASK ((unsigned int) 0x00000001) // Halt requested in NVIC +#define SCB_DFSR_HALTED ((unsigned int) 0x00000001) +#define SCB_DFSR_BKPT_MASK ((unsigned int) 0x00000002) // BKPT instruction executed +#define SCB_DFSR_BKPT ((unsigned int) 0x00000002) +#define SCB_DFSR_DWTTRAP_MASK ((unsigned int) 0x00000004) // DWT match occurred +#define SCB_DFSR_DWTTRAP ((unsigned int) 0x00000004) +#define SCB_DFSR_VCATCH_MASK ((unsigned int) 0x00000008) // Vector fetch occurred +#define SCB_DFSR_VCATCH ((unsigned int) 0x00000008) +#define SCB_DFSR_EXTERNAL_MASK ((unsigned int) 0x00000010) // EDBGRQ signal asserted +#define SCB_DFSR_EXTERNAL ((unsigned int) 0x00000010) + +/* SCB_MEMREMAP (System memory remap register) + The system memory remap register selects whether the ARM interrupt vectors are read + from the boot ROM, the flash, or the SRAM. */ + +#define SCB_MEMREMAP_MODE_BOOTLOADER ((unsigned int) 0x00000000) // Interrupt vectors are remapped to Boot ROM +#define SCB_MEMREMAP_MODE_RAM ((unsigned int) 0x00000001) // Interrupt vectors are remapped to Static ROM +#define SCB_MEMREMAP_MODE_FLASH ((unsigned int) 0x00000002) // Interrupt vectors are not remapped and reside in Flash +#define SCB_MEMREMAP_MASK ((unsigned int) 0x00000003) + +/* PRESETCTRL (Peripheral reset control register) */ + +#define SCB_PRESETCTRL_SSP0_RESETENABLED ((unsigned int) 0x00000000) +#define SCB_PRESETCTRL_SSP0_RESETDISABLED ((unsigned int) 0x00000001) +#define SCB_PRESETCTRL_SSP0_MASK ((unsigned int) 0x00000001) +#define SCB_PRESETCTRL_I2C_RESETENABLED ((unsigned int) 0x00000000) +#define SCB_PRESETCTRL_I2C_RESETDISABLED ((unsigned int) 0x00000002) +#define SCB_PRESETCTRL_I2C_MASK ((unsigned int) 0x00000002) + +/* SYSPLLCTRL (System PLL control register) + This register connects and enables the system PLL and configures the PLL multiplier and + divider values. The PLL accepts an input frequency from 10 MHz to 25 MHz from various + clock sources. The input frequency is multiplied up to a high frequency, then divided down + to provide the actual clock used by the CPU, peripherals, and optionally the USB + subsystem. Note that the USB subsystem has its own dedicated PLL. The PLL can + produce a clock up to the maximum allowed for the CPU, which is 72 MHz. */ + +#define SCB_PLLCTRL_MULT_1 ((unsigned int) 0x00000000) +#define SCB_PLLCTRL_MULT_2 ((unsigned int) 0x00000001) +#define SCB_PLLCTRL_MULT_3 ((unsigned int) 0x00000002) +#define SCB_PLLCTRL_MULT_4 ((unsigned int) 0x00000003) +#define SCB_PLLCTRL_MULT_5 ((unsigned int) 0x00000004) +#define SCB_PLLCTRL_MULT_6 ((unsigned int) 0x00000005) +#define SCB_PLLCTRL_MULT_7 ((unsigned int) 0x00000006) +#define SCB_PLLCTRL_MULT_8 ((unsigned int) 0x00000007) +#define SCB_PLLCTRL_MULT_9 ((unsigned int) 0x00000008) +#define SCB_PLLCTRL_MULT_10 ((unsigned int) 0x00000009) +#define SCB_PLLCTRL_MULT_11 ((unsigned int) 0x0000000A) +#define SCB_PLLCTRL_MULT_12 ((unsigned int) 0x0000000B) +#define SCB_PLLCTRL_MULT_13 ((unsigned int) 0x0000000C) +#define SCB_PLLCTRL_MULT_14 ((unsigned int) 0x0000000D) +#define SCB_PLLCTRL_MULT_15 ((unsigned int) 0x0000000E) +#define SCB_PLLCTRL_MULT_16 ((unsigned int) 0x0000000F) +#define SCB_PLLCTRL_MULT_17 ((unsigned int) 0x00000010) +#define SCB_PLLCTRL_MULT_18 ((unsigned int) 0x00000011) +#define SCB_PLLCTRL_MULT_19 ((unsigned int) 0x00000012) +#define SCB_PLLCTRL_MULT_20 ((unsigned int) 0x00000013) +#define SCB_PLLCTRL_MULT_21 ((unsigned int) 0x00000014) +#define SCB_PLLCTRL_MULT_22 ((unsigned int) 0x00000015) +#define SCB_PLLCTRL_MULT_23 ((unsigned int) 0x00000016) +#define SCB_PLLCTRL_MULT_24 ((unsigned int) 0x00000017) +#define SCB_PLLCTRL_MULT_25 ((unsigned int) 0x00000018) +#define SCB_PLLCTRL_MULT_26 ((unsigned int) 0x00000019) +#define SCB_PLLCTRL_MULT_27 ((unsigned int) 0x0000001A) +#define SCB_PLLCTRL_MULT_28 ((unsigned int) 0x0000001B) +#define SCB_PLLCTRL_MULT_29 ((unsigned int) 0x0000001C) +#define SCB_PLLCTRL_MULT_30 ((unsigned int) 0x0000001D) +#define SCB_PLLCTRL_MULT_31 ((unsigned int) 0x0000001E) +#define SCB_PLLCTRL_MULT_32 ((unsigned int) 0x0000001F) +#define SCB_PLLCTRL_MULT_MASK ((unsigned int) 0x0000001F) +#define SCB_PLLCTRL_DIV_2 ((unsigned int) 0x00000000) +#define SCB_PLLCTRL_DIV_4 ((unsigned int) 0x00000020) +#define SCB_PLLCTRL_DIV_8 ((unsigned int) 0x00000040) +#define SCB_PLLCTRL_DIV_16 ((unsigned int) 0x00000060) +#define SCB_PLLCTRL_DIV_BIT (5) +#define SCB_PLLCTRL_DIV_MASK ((unsigned int) 0x00000060) +#define SCB_PLLCTRL_DIRECT_MASK ((unsigned int) 0x00000080) // Direct CCO clock output control +#define SCB_PLLCTRL_BYPASS_MASK ((unsigned int) 0x00000100) // Input clock bypass control +#define SCB_PLLCTRL_MASK ((unsigned int) 0x000001FF) + +/* SYSPLLSTAT (System PLL status register) + This register is a Read-only register and supplies the PLL lock status */ + +#define SCB_PLLSTAT_LOCK ((unsigned int) 0x00000001) // 0 = PLL not locked, 1 = PLL locked +#define SCB_PLLSTAT_LOCK_MASK ((unsigned int) 0x00000001) + +/* USBPLLCTRL (USB PLL control register) + The USB PLL is identical to the system PLL and is used to provide a dedicated clock to + the USB block if available. The USB PLL should be always connected to the system + oscillator to produce a stable USB clock. */ + +#define SCB_USBPLLCTRL_MULT_1 ((unsigned int) 0x00000000) +#define SCB_USBPLLCTRL_MULT_2 ((unsigned int) 0x00000001) +#define SCB_USBPLLCTRL_MULT_3 ((unsigned int) 0x00000002) +#define SCB_USBPLLCTRL_MULT_4 ((unsigned int) 0x00000003) +#define SCB_USBPLLCTRL_MULT_5 ((unsigned int) 0x00000004) +#define SCB_USBPLLCTRL_MULT_6 ((unsigned int) 0x00000005) +#define SCB_USBPLLCTRL_MULT_7 ((unsigned int) 0x00000006) +#define SCB_USBPLLCTRL_MULT_8 ((unsigned int) 0x00000007) +#define SCB_USBPLLCTRL_MULT_9 ((unsigned int) 0x00000008) +#define SCB_USBPLLCTRL_MULT_10 ((unsigned int) 0x00000009) +#define SCB_USBPLLCTRL_MULT_11 ((unsigned int) 0x0000000A) +#define SCB_USBPLLCTRL_MULT_12 ((unsigned int) 0x0000000B) +#define SCB_USBPLLCTRL_MULT_13 ((unsigned int) 0x0000000C) +#define SCB_USBPLLCTRL_MULT_14 ((unsigned int) 0x0000000D) +#define SCB_USBPLLCTRL_MULT_15 ((unsigned int) 0x0000000E) +#define SCB_USBPLLCTRL_MULT_16 ((unsigned int) 0x0000000F) +#define SCB_USBPLLCTRL_MULT_17 ((unsigned int) 0x00000010) +#define SCB_USBPLLCTRL_MULT_18 ((unsigned int) 0x00000011) +#define SCB_USBPLLCTRL_MULT_19 ((unsigned int) 0x00000012) +#define SCB_USBPLLCTRL_MULT_20 ((unsigned int) 0x00000013) +#define SCB_USBPLLCTRL_MULT_21 ((unsigned int) 0x00000014) +#define SCB_USBPLLCTRL_MULT_22 ((unsigned int) 0x00000015) +#define SCB_USBPLLCTRL_MULT_23 ((unsigned int) 0x00000016) +#define SCB_USBPLLCTRL_MULT_24 ((unsigned int) 0x00000017) +#define SCB_USBPLLCTRL_MULT_25 ((unsigned int) 0x00000018) +#define SCB_USBPLLCTRL_MULT_26 ((unsigned int) 0x00000019) +#define SCB_USBPLLCTRL_MULT_27 ((unsigned int) 0x0000001A) +#define SCB_USBPLLCTRL_MULT_28 ((unsigned int) 0x0000001B) +#define SCB_USBPLLCTRL_MULT_29 ((unsigned int) 0x0000001C) +#define SCB_USBPLLCTRL_MULT_30 ((unsigned int) 0x0000001D) +#define SCB_USBPLLCTRL_MULT_31 ((unsigned int) 0x0000001E) +#define SCB_USBPLLCTRL_MULT_32 ((unsigned int) 0x0000001F) +#define SCB_USBPLLCTRL_MULT_MASK ((unsigned int) 0x0000001F) +#define SCB_USBPLLCTRL_DIV_2 ((unsigned int) 0x00000000) +#define SCB_USBPLLCTRL_DIV_4 ((unsigned int) 0x00000020) +#define SCB_USBPLLCTRL_DIV_8 ((unsigned int) 0x00000040) +#define SCB_USBPLLCTRL_DIV_16 ((unsigned int) 0x00000060) +#define SCB_USBPLLCTRL_DIV_BIT (5) +#define SCB_USBPLLCTRL_DIV_MASK ((unsigned int) 0x00000060) +#define SCB_USBPLLCTRL_DIRECT_MASK ((unsigned int) 0x00000080) // Direct CCO clock output control +#define SCB_USBPLLCTRL_BYPASS_MASK ((unsigned int) 0x00000100) // Input clock bypass control +#define SCB_USBPLLCTRL_MASK ((unsigned int) 0x000001FF) + +/* USBPLLSTAT (System PLL status register) + This register is a Read-only register and supplies the PLL lock status. */ + +#define SCB_USBPLLSTAT_LOCK ((unsigned int) 0x00000001) // 0 = PLL not locked, 1 = PLL locked +#define SCB_USBPLLSTAT_LOCK_MASK ((unsigned int) 0x00000001) + +/* SYSOSCCTRL (System oscillator control register) + This register configures the frequency range for the system oscillator. */ + +#define SCB_SYSOSCCTRL_BYPASS_DISABLED ((unsigned int) 0x00000000) // Oscillator is not bypassed. +#define SCB_SYSOSCCTRL_BYPASS_ENABLED ((unsigned int) 0x00000001) // Bypass enabled +#define SCB_SYSOSCCTRL_BYPASS_MASK ((unsigned int) 0x00000001) +#define SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ ((unsigned int) 0x00000000) // 1-20 MHz frequency range +#define SCB_SYSOSCCTRL_FREQRANGE_15TO25MHZ ((unsigned int) 0x00000002) // 15-25 MHz frequency range +#define SCB_SYSOSCCTRL_FREQRANGE_MASK ((unsigned int) 0x00000002) + +/* WDTOSCTRL (Watchdog oscillator control register) + This register configures the watchdog oscillator. The oscillator consists of an analog and a + digital part. The analog part contains the oscillator function and generates an analog clock + (Fclkana). With the digital part, the analog output clock (Fclkana) can be divided to the + required output clock frequency wdt_osc_clk. The analog output frequency (Fclkana) can + be adjusted with the FREQSEL bits between 500 kHz and 3.7 MHz. With the digital part + Fclkana will be divided (divider ratios = 2, 4,...,64) to wdt_osc_clk using the DIVSEL bits.*/ + +#define SCB_WDTOSCCTRL_DIVSEL_DIV2 ((unsigned int) 0x00000000) // Reset value +#define SCB_WDTOSCCTRL_DIVSEL_DIV4 ((unsigned int) 0x00000001) +#define SCB_WDTOSCCTRL_DIVSEL_DIV6 ((unsigned int) 0x00000002) +#define SCB_WDTOSCCTRL_DIVSEL_DIV8 ((unsigned int) 0x00000003) +#define SCB_WDTOSCCTRL_DIVSEL_DIV10 ((unsigned int) 0x00000004) +#define SCB_WDTOSCCTRL_DIVSEL_DIV12 ((unsigned int) 0x00000005) +#define SCB_WDTOSCCTRL_DIVSEL_DIV14 ((unsigned int) 0x00000006) +#define SCB_WDTOSCCTRL_DIVSEL_DIV16 ((unsigned int) 0x00000007) +#define SCB_WDTOSCCTRL_DIVSEL_DIV18 ((unsigned int) 0x00000008) +#define SCB_WDTOSCCTRL_DIVSEL_DIV20 ((unsigned int) 0x00000009) +#define SCB_WDTOSCCTRL_DIVSEL_DIV22 ((unsigned int) 0x0000000A) +#define SCB_WDTOSCCTRL_DIVSEL_DIV24 ((unsigned int) 0x0000000B) +#define SCB_WDTOSCCTRL_DIVSEL_DIV26 ((unsigned int) 0x0000000C) +#define SCB_WDTOSCCTRL_DIVSEL_DIV28 ((unsigned int) 0x0000000D) +#define SCB_WDTOSCCTRL_DIVSEL_DIV30 ((unsigned int) 0x0000000E) +#define SCB_WDTOSCCTRL_DIVSEL_DIV32 ((unsigned int) 0x0000000F) +#define SCB_WDTOSCCTRL_DIVSEL_DIV34 ((unsigned int) 0x00000010) +#define SCB_WDTOSCCTRL_DIVSEL_DIV36 ((unsigned int) 0x00000011) +#define SCB_WDTOSCCTRL_DIVSEL_DIV38 ((unsigned int) 0x00000012) +#define SCB_WDTOSCCTRL_DIVSEL_DIV40 ((unsigned int) 0x00000013) +#define SCB_WDTOSCCTRL_DIVSEL_DIV42 ((unsigned int) 0x00000014) +#define SCB_WDTOSCCTRL_DIVSEL_DIV44 ((unsigned int) 0x00000015) +#define SCB_WDTOSCCTRL_DIVSEL_DIV46 ((unsigned int) 0x00000016) +#define SCB_WDTOSCCTRL_DIVSEL_DIV48 ((unsigned int) 0x00000017) +#define SCB_WDTOSCCTRL_DIVSEL_DIV50 ((unsigned int) 0x00000018) +#define SCB_WDTOSCCTRL_DIVSEL_DIV52 ((unsigned int) 0x00000019) +#define SCB_WDTOSCCTRL_DIVSEL_DIV54 ((unsigned int) 0x0000001A) +#define SCB_WDTOSCCTRL_DIVSEL_DIV56 ((unsigned int) 0x0000001B) +#define SCB_WDTOSCCTRL_DIVSEL_DIV58 ((unsigned int) 0x0000001C) +#define SCB_WDTOSCCTRL_DIVSEL_DIV60 ((unsigned int) 0x0000001D) +#define SCB_WDTOSCCTRL_DIVSEL_DIV62 ((unsigned int) 0x0000001E) +#define SCB_WDTOSCCTRL_DIVSEL_DIV64 ((unsigned int) 0x0000001F) +#define SCB_WDTOSCCTRL_DIVSEL_MASK ((unsigned int) 0x0000001F) +#define SCB_WDTOSCCTRL_FREQSEL_0_5MHZ ((unsigned int) 0x00000020) +#define SCB_WDTOSCCTRL_FREQSEL_0_8MHZ ((unsigned int) 0x00000040) +#define SCB_WDTOSCCTRL_FREQSEL_1_1MHZ ((unsigned int) 0x00000060) +#define SCB_WDTOSCCTRL_FREQSEL_1_4MHZ ((unsigned int) 0x00000080) +#define SCB_WDTOSCCTRL_FREQSEL_1_6MHZ ((unsigned int) 0x000000A0) // Reset value +#define SCB_WDTOSCCTRL_FREQSEL_1_8MHZ ((unsigned int) 0x000000C0) +#define SCB_WDTOSCCTRL_FREQSEL_2_0MHZ ((unsigned int) 0x000000E0) +#define SCB_WDTOSCCTRL_FREQSEL_2_2MHZ ((unsigned int) 0x00000100) +#define SCB_WDTOSCCTRL_FREQSEL_2_4MHZ ((unsigned int) 0x00000120) +#define SCB_WDTOSCCTRL_FREQSEL_2_6MHZ ((unsigned int) 0x00000140) +#define SCB_WDTOSCCTRL_FREQSEL_2_7MHZ ((unsigned int) 0x00000160) +#define SCB_WDTOSCCTRL_FREQSEL_2_9MHZ ((unsigned int) 0x00000180) +#define SCB_WDTOSCCTRL_FREQSEL_3_1MHZ ((unsigned int) 0x000001A0) +#define SCB_WDTOSCCTRL_FREQSEL_3_2MHZ ((unsigned int) 0x000001C0) +#define SCB_WDTOSCCTRL_FREQSEL_3_4MHZ ((unsigned int) 0x000001E0) +#define SCB_WDTOSCCTRL_FREQSEL_MASK ((unsigned int) 0x000001E0) + +/* IRCCTRL (Internal resonant crystal control register) + This register is used to trim the on-chip 12 MHz oscillator. The trim value is factory-preset + and written by the boot code on start-up. */ + +#define SCB_IRCCTRL_MASK ((unsigned int) 0x000000FF) + +/* SYSRSTSTAT (System reset status register) + The SYSRSTSTAT register shows the source of the latest reset event. The bits are + cleared by writing a one to any of the bits. The POR event clears all other bits in this + register, but if another reset signal (e.g., EXTRST) remains asserted after the POR signal + is negated, then its bit is set to detected. */ + +#define SCB_RESETSTAT_POR_MASK ((unsigned int) 0x00000001) // POR reset status +#define SCB_RESETSTAT_EXTRST_MASK ((unsigned int) 0x00000002) // Status of the external reset pin +#define SCB_RESETSTAT_WDT_MASK ((unsigned int) 0x00000004) // Status of the watchdog reset +#define SCB_RESETSTAT_BOD_MASK ((unsigned int) 0x00000008) // Status of the brown-out detect reset +#define SCB_RESETSTAT_SYSRST_MASK ((unsigned int) 0x00000010) // Status of the software system reset +#define SCB_RESETSTAT_MASK ((unsigned int) 0x00000010) + +/* SYSPLLCLKSEL (System PLL clock source select register) + This register selects the clock source for the system PLL. The SYSPLLCLKUEN register + must be toggled from LOW to HIGH for the update to take effect. + Remark: The system oscillator must be selected if the system PLL is used to generate a + 48 MHz clock to the USB block. +*/ + +#define SCB_CLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) +#define SCB_CLKSEL_SOURCE_MAINOSC ((unsigned int) 0x00000001) +#define SCB_CLKSEL_SOURCE_RTCOSC ((unsigned int) 0x00000002) +#define SCB_CLKSEL_SOURCE_MASK ((unsigned int) 0x00000002) + +/* SYSPLLUEN (System PLL clock source update enable register) + This register updates the clock source of the system PLL with the new input clock after the + SYSPLLCLKSEL register has been written to. In order for the update to take effect, first + write a zero to the SYSPLLUEN register and then write a one to SYSPLLUEN. */ + +#define SCB_PLLCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_PLLCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_PLLCLKUEN_MASK ((unsigned int) 0x00000001) + +/* USBPLLCLKSEL (USB PLL clock source select register) + his register selects the clock source for the dedicated USB PLL. The SYSPLLCLKUEN + register must be toggled from LOW to HIGH for the update to take effect. + Remark: Always select the system oscillator to produce a stable 48 MHz clock for + the USB block. */ + +#define SCB_USBPLLCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Do NOT use (even though this is the default value) +#define SCB_USBPLLCLKSEL_SOURCE_MAINOSC ((unsigned int) 0x00000001) // Main oscillator should always be used for USB clock +#define SCB_USBPLLCLKSEL_SOURCE_MASK ((unsigned int) 0x00000002) + +/* USBPLLUEN (USB PLL clock source update enable register) + This register updates the clock source of the USB PLL with the new input clock after the + USBPLLCLKSEL register has been written to. In order for the update to take effect at the + USB PLL input, first write a zero to the USBPLLUEN register and then write a one to + USBPLLUEN. */ + +#define SCB_USBPLLCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBPLLCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_USBPLLCLKUEN_MASK ((unsigned int) 0x00000001) + +/* MAINCLKSEL (Main clock source select register) + This register selects the main system clock which can be either the output from the + system PLL or the IRC, system, or Watchdog oscillators directly. The main system clock + clocks the core, the peripherals, and optionally the USB block. + The MAINCLKUEN register must be toggled from LOW to HIGH for the update to take effect.*/ + +#define SCB_MAINCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Use IRC oscillator for main clock source +#define SCB_MAINCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use Input clock to system PLL for main clock source +#define SCB_MAINCLKSEL_SOURCE_WDTOSC ((unsigned int) 0x00000002) // Use watchdog oscillator for main clock source +#define SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT ((unsigned int) 0x00000003) // Use system PLL clock out for main clock source +#define SCB_MAINCLKSEL_MASK ((unsigned int) 0x00000003) + +/* MAINCLKUEN (Main clock source update enable register) + This register updates the clock source of the main clock with the new input clock after the + MAINCLKSEL register has been written to. In order for the update to take effect, first write + a zero to the MAINUEN register and then write a one to MAINCLKUEN. */ + +#define SCB_MAINCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_MAINCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_MAINCLKUEN_MASK ((unsigned int) 0x00000001) + +/* SYSAHBCLKDIV (System AHB clock divider register) + This register divides the main clock to provide the system clock to the core, memories, + and the peripherals. The system clock can be shut down completely by setting the DIV + bits to 0x0. */ + +#define SCB_SYSAHBCLKDIV_DISABLE ((unsigned int) 0x00000000) // 0 will shut the system clock down completely +#define SCB_SYSAHBCLKDIV_DIV1 ((unsigned int) 0x00000001) // 1, 2 or 4 are the most common values +#define SCB_SYSAHBCLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_SYSAHBCLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_SYSAHBCLKDIV_MASK ((unsigned int) 0x000000FF) // AHB clock divider can be from 0 to 255 + +/* AHBCLKCTRL (System AHB clock control register) + The AHBCLKCTRL register enables the clocks to individual system and peripheral blocks. + The system clock (sys_ahb_clk[0], bit 0 in the AHBCLKCTRL register) provides the clock + for the AHB to APB bridge, the AHB matrix, the ARM Cortex-M3, the Syscon block, and + the PMU. This clock cannot be disabled. */ + +#define SCB_SYSAHBCLKCTRL_SYS ((unsigned int) 0x00000001) // Enables clock for AHB and APB bridges, FCLK, HCLK, SysCon and PMU +#define SCB_SYSAHBCLKCTRL_SYS_MASK ((unsigned int) 0x00000001) +#define SCB_SYSAHBCLKCTRL_ROM ((unsigned int) 0x00000002) // Enables clock for ROM +#define SCB_SYSAHBCLKCTRL_ROM_MASK ((unsigned int) 0x00000002) +#define SCB_SYSAHBCLKCTRL_RAM ((unsigned int) 0x00000004) // Enables clock for SRAM +#define SCB_SYSAHBCLKCTRL_RAM_MASK ((unsigned int) 0x00000004) +#define SCB_SYSAHBCLKCTRL_FLASH1 ((unsigned int) 0x00000008) // Enables clock for flash1 +#define SCB_SYSAHBCLKCTRL_FLASH1_MASK ((unsigned int) 0x00000008) +#define SCB_SYSAHBCLKCTRL_FLASH2 ((unsigned int) 0x00000010) // Enables clock for flash2 +#define SCB_SYSAHBCLKCTRL_FLASH2_MASK ((unsigned int) 0x00000010) +#define SCB_SYSAHBCLKCTRL_I2C ((unsigned int) 0x00000020) // Enables clock for I2C +#define SCB_SYSAHBCLKCTRL_I2C_MASK ((unsigned int) 0x00000020) +#define SCB_SYSAHBCLKCTRL_GPIO ((unsigned int) 0x00000040) // Enables clock for GPIO +#define SCB_SYSAHBCLKCTRL_GPIO_MASK ((unsigned int) 0x00000040) +#define SCB_SYSAHBCLKCTRL_CT16B0 ((unsigned int) 0x00000080) // Enables clock for 16-bit counter/timer 0 +#define SCB_SYSAHBCLKCTRL_CT16B0_MASK ((unsigned int) 0x00000080) +#define SCB_SYSAHBCLKCTRL_CT16B1 ((unsigned int) 0x00000100) // Enables clock for 16-bit counter/timer 1 +#define SCB_SYSAHBCLKCTRL_CT16B1_MASK ((unsigned int) 0x00000100) +#define SCB_SYSAHBCLKCTRL_CT32B0 ((unsigned int) 0x00000200) // Enables clock for 32-bit counter/timer 0 +#define SCB_SYSAHBCLKCTRL_CT32B0_MASK ((unsigned int) 0x00000200) +#define SCB_SYSAHBCLKCTRL_CT32B1 ((unsigned int) 0x00000400) // Enables clock for 32-bit counter/timer 1 +#define SCB_SYSAHBCLKCTRL_CT32B1_MASK ((unsigned int) 0x00000400) +#define SCB_SYSAHBCLKCTRL_SSP0 ((unsigned int) 0x00000800) // Enables clock for SSP0 +#define SCB_SYSAHBCLKCTRL_SSP0_MASK ((unsigned int) 0x00000800) +#define SCB_SYSAHBCLKCTRL_UART ((unsigned int) 0x00001000) // Enables clock for UART. UART pins must be configured +#define SCB_SYSAHBCLKCTRL_UART_MASK ((unsigned int) 0x00001000) // in the IOCON block before the UART clock can be enabled. +#define SCB_SYSAHBCLKCTRL_ADC ((unsigned int) 0x00002000) // Enables clock for ADC +#define SCB_SYSAHBCLKCTRL_ADC_MASK ((unsigned int) 0x00002000) +#define SCB_SYSAHBCLKCTRL_USB_REG ((unsigned int) 0x00004000) // Enables clock for USB_REG +#define SCB_SYSAHBCLKCTRL_USB_REG_MASK ((unsigned int) 0x00004000) +#define SCB_SYSAHBCLKCTRL_WDT ((unsigned int) 0x00008000) // Enables clock for watchdog timer +#define SCB_SYSAHBCLKCTRL_WDT_MASK ((unsigned int) 0x00008000) +#define SCB_SYSAHBCLKCTRL_IOCON ((unsigned int) 0x00010000) // Enables clock for IO configuration block +#define SCB_SYSAHBCLKCTRL_IOCON_MASK ((unsigned int) 0x00010000) +#define SCB_SYSAHBCLKCTRL_ALL_MASK ((unsigned int) 0x0001FFFF) + +/* SSP0CLKDIV (SSP0 clock divider register) + This register configures the SSP0 peripheral clock SSP_PCLK. The SSP_PCLK can be + shut down by setting the DIV bits to 0x0. It can be set from 1..255. */ + +#define SCB_SSP0CLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_SSP0CLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide SSP0 clock by 1 (can be set from 1..255) +#define SCB_SSP0CLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_SSP0CLKDIV_DIV3 ((unsigned int) 0x00000003) +#define SCB_SSP0CLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_SSP0CLKDIV_DIV6 ((unsigned int) 0x00000006) +#define SCB_SSP0CLKDIV_DIV10 ((unsigned int) 0x0000000A) +#define SCB_SSP0CLKDIV_DIV12 ((unsigned int) 0x0000000C) +#define SCB_SSP0CLKDIV_DIV20 ((unsigned int) 0x00000014) +#define SCB_SSP0CLKDIV_DIV40 ((unsigned int) 0x00000028) +#define SCB_SSP0CLKDIV_MASK ((unsigned int) 0x000000FF) + +/* UARTCLKDIV (UART clock divider register) + This register configures the UART peripheral. The UART_PCLK can be shut down by + setting the DIV bits to 0x0. + Remark: Note that the UART pins must be configured in the IOCON block before the + UART clock can be enabled. */ + +#define SCB_UARTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_UARTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide UART clock by 1 (can be set from 1..255) +#define SCB_UARTCLKDIV_DIV2 ((unsigned int) 0x00000002) +#define SCB_UARTCLKDIV_DIV4 ((unsigned int) 0x00000004) +#define SCB_UARTCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* SYSTICKCLKDIV (SYSTICK clock divider register) + This register configures the SYSTICK peripheral clock. The SYSTICK timer clock can be + shut down by setting the DIV bits to 0x0. */ + +#define SCB_SYSTICKCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_SYSTICKCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide SYSTICK clock by 1 (can be set from 1..255) +#define SCB_SYSTICKCLKDIV_DIV2 ((unsigned int) 0x00000002) // Divide SYSTICK clock by 2 +#define SCB_SYSTICKCLKDIV_DIV4 ((unsigned int) 0x00000004) // Divide SYSTICK clock by 4 +#define SCB_SYSTICKCLKDIV_DIV8 ((unsigned int) 0x00000008) // Divide SYSTICK clock by 8 +#define SCB_SYSTICKCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* USBCLKSEL (USB clock source select register) + This register selects the clock source for the USB usb_clk. The clock source can be either + the USB PLL output or the main clock, and the clock can be further divided by the + USBCLKDIV register to obtain a 48 MHz clock. The USBCLKUEN register must be toggled from + LOW to HIGH for the update to take effect. */ + +#define SCB_USBCLKSEL_SOURCE_USBPLLOUT ((unsigned int) 0x00000000) // USB PLL output +#define SCB_USBCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_USBCLKSEL_MASK ((unsigned int) 0x00000003) + +/* USBCLKUEN (USB clock source update enable register) + This register updates the clock source of the USB with the new input clock after the + USBCLKSEL register has been written to. In order for the update to take effect, first write + a zero to the USBCLKUEN register and then write a one to USBCLKUEN. */ + +#define SCB_USBCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_USBCLKUEN_MASK ((unsigned int) 0x00000001) + +/* USBCLKDIV (USB clock divider register) + This register allows the USB clock usb_clk to be divided to 48 MHz. The usb_clk can be + shut down by setting the DIV bits to 0x0. */ + +#define SCB_USBCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_USBCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide USB clock by 1 (can be set from 1..255) +#define SCB_USBCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* WDTCLKSEL (WDT clock source select register) + This register selects the clock source for the watchdog timer. The WDTCLKUEN register + must be toggled from LOW to HIGH for the update to take effect. */ + +#define SCB_WDTCLKSEL_SOURCE_INTERNALOSC ((unsigned int) 0x00000000) // Use the internal oscillator +#define SCB_WDTCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC ((unsigned int) 0x00000002) // Use the watchdog oscillator +#define SCB_WDTCLKSEL_MASK ((unsigned int) 0x00000003) + +/* WDTCLKUEN (WDT clock source update enable register) + This register updates the clock source of the watchdog timer with the new input clock after + the WDTCLKSEL register has been written to. In order for the update to take effect at the + input of the watchdog timer, first write a zero to the WDTCLKUEN register and then write + a one to WDTCLKUEN. */ + +#define SCB_WDTCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_WDTCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_WDTCLKUEN_MASK ((unsigned int) 0x00000001) + +/* WDTCLKDIV (WDT clock divider register) + This register determines the divider values for the watchdog clock wdt_clk. */ + +#define SCB_WDTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_WDTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide clock by 1 (can be set from 1..255) +#define SCB_WDTCLKDIV_MASK ((unsigned int) 0x000000FF) + +/* CLKOUTCLKSEL (CLKOUT clock source select register) + This register configures the clkout_clk signal to be output on the CLKOUT pin. All three + oscillators and the main clock can be selected for the clkout_clk clock. + The CLKOUTCLKUEN register must be toggled from LOW to HIGH for the update to take effect. */ + +#define SCB_CLKOUTCLKSEL_SOURCE_USBPLLOUT ((unsigned int) 0x00000000) // USB PLL output +#define SCB_CLKOUTCLKSEL_SOURCE_INPUTCLOCK ((unsigned int) 0x00000001) // Use the main clock +#define SCB_CLKOUTCLKSEL_MASK ((unsigned int) 0x00000003) + +/* CLKOUTUEN (CLKOUT clock source update enable register) + This register updates the clock source of the CLKOUT pin with the new clock after the + CLKOUTCLKSEL register has been written to. In order for the update to take effect at the + input of the CLKOUT pin, first write a zero to the CLKCLKUEN register and then write a + one to CLKCLKUEN. */ + +#define SCB_CLKOUTCLKUEN_DISABLE ((unsigned int) 0x00000000) +#define SCB_CLKOUTCLKUEN_UPDATE ((unsigned int) 0x00000001) +#define SCB_CLKOUTCLKUEN_MASK ((unsigned int) 0x00000001) + +/* CLKOUTCLKDIV (CLKOUT clock divider register) + This register determines the divider value for the clkout_clk signal on the CLKOUT pin. */ + +#define SCB_CLKOUTCLKDIV_DISABLE ((unsigned int) 0x00000000) +#define SCB_CLKOUTCLKDIV_DIV1 ((unsigned int) 0x00000001) // Divide clock by 1 (can be set from 1..255) +#define SCB_CLKOUTCLKDIV_MASK ((unsigned int) 0x000000FF) + + +/* PIOPORCAP0 (POR captured PIO status register 0) + The PIOPORCAP0 register captures the state (HIGH or LOW) of the PIO pins of ports 0,1, + and 2 (pins PIO2_0 to PIO2_7) at power-on-reset. Each bit represents the reset state of + one GPIO pin. This register is a read-only status register. */ + +#define SCB_PIOPORCAP0_PIO0_0 ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP0_PIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP0_PIO0_1 ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP0_PIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP0_PIO0_2 ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP0_PIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP0_PIO0_3 ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP0_PIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP0_PIO0_4 ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP0_PIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP0_PIO0_5 ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP0_PIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP0_PIO0_6 ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP0_PIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP0_PIO0_7 ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP0_PIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP0_PIO0_8 ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP0_PIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP0_PIO0_9 ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP0_PIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP0_PIO0_10 ((unsigned int) 0x00000400) +#define SCB_PIOPORCAP0_PIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_PIOPORCAP0_PIO0_11 ((unsigned int) 0x00000800) +#define SCB_PIOPORCAP0_PIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_PIOPORCAP0_PIO1_0 ((unsigned int) 0x00001000) +#define SCB_PIOPORCAP0_PIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_PIOPORCAP0_PIO1_1 ((unsigned int) 0x00002000) +#define SCB_PIOPORCAP0_PIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_PIOPORCAP0_PIO1_2 ((unsigned int) 0x00004000) +#define SCB_PIOPORCAP0_PIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_PIOPORCAP0_PIO1_3 ((unsigned int) 0x00008000) +#define SCB_PIOPORCAP0_PIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_PIOPORCAP0_PIO1_4 ((unsigned int) 0x00010000) +#define SCB_PIOPORCAP0_PIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_PIOPORCAP0_PIO1_5 ((unsigned int) 0x00020000) +#define SCB_PIOPORCAP0_PIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_PIOPORCAP0_PIO1_6 ((unsigned int) 0x00040000) +#define SCB_PIOPORCAP0_PIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_PIOPORCAP0_PIO1_7 ((unsigned int) 0x00080000) +#define SCB_PIOPORCAP0_PIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_PIOPORCAP0_PIO1_8 ((unsigned int) 0x00100000) +#define SCB_PIOPORCAP0_PIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_PIOPORCAP0_PIO1_9 ((unsigned int) 0x00200000) +#define SCB_PIOPORCAP0_PIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_PIOPORCAP0_PIO1_10 ((unsigned int) 0x00400000) +#define SCB_PIOPORCAP0_PIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_PIOPORCAP0_PIO1_11 ((unsigned int) 0x00800000) +#define SCB_PIOPORCAP0_PIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_PIOPORCAP0_PIO2_0 ((unsigned int) 0x01000000) +#define SCB_PIOPORCAP0_PIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_PIOPORCAP0_PIO2_1 ((unsigned int) 0x02000000) +#define SCB_PIOPORCAP0_PIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_PIOPORCAP0_PIO2_2 ((unsigned int) 0x04000000) +#define SCB_PIOPORCAP0_PIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_PIOPORCAP0_PIO2_3 ((unsigned int) 0x08000000) +#define SCB_PIOPORCAP0_PIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_PIOPORCAP0_PIO2_4 ((unsigned int) 0x10000000) +#define SCB_PIOPORCAP0_PIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_PIOPORCAP0_PIO2_5 ((unsigned int) 0x20000000) +#define SCB_PIOPORCAP0_PIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_PIOPORCAP0_PIO2_6 ((unsigned int) 0x40000000) +#define SCB_PIOPORCAP0_PIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_PIOPORCAP0_PIO2_7 ((unsigned int) 0x80000000) +#define SCB_PIOPORCAP0_PIO2_7_MASK ((unsigned int) 0x80000000) + +/* PIOPORCAP1 (POR captured PIO status register 1) + The PIOPORCAP1 register captures the state (HIGH or LOW) of the PIO pins of port 2 + (PIO2_8 to PIO2_11) and port 3 at power-on-reset. Each bit represents the reset state of + one PIO pin. This register is a read-only status register. */ + +#define SCB_PIOPORCAP1_PIO2_8 ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP1_PIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_PIOPORCAP1_PIO2_9 ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP1_PIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_PIOPORCAP1_PIO2_10 ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP1_PIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_PIOPORCAP1_PIO2_11 ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP1_PIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_PIOPORCAP1_PIO3_0 ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP1_PIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_PIOPORCAP1_PIO3_1 ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP1_PIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_PIOPORCAP1_PIO3_2 ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP1_PIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_PIOPORCAP1_PIO3_3 ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP1_PIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_PIOPORCAP1_PIO3_4 ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP1_PIO3_4_MASK ((unsigned int) 0x00000100) +#define SCB_PIOPORCAP1_PIO3_5 ((unsigned int) 0x00000200) +#define SCB_PIOPORCAP1_PIO3_5_MASK ((unsigned int) 0x00000200) + +/* BODCTRL (Brown-out detection control register) + The BOD control register selects four separate threshold values for sending a BOD + interrupt to the NVIC. Only one level is allowed for forced reset. */ + +#define SCB_BODCTRL_RSTLEVEL_MASK ((unsigned int) 0x00000003) +#define SCB_BODCTRL_INTLEVEL_1_69V_1_84V ((unsigned int) 0x00000000) +#define SCB_BODCTRL_INTLEVEL_2_29V_2_44V ((unsigned int) 0x00000004) +#define SCB_BODCTRL_INTLEVEL_2_59V_2_74V ((unsigned int) 0x00000008) +#define SCB_BODCTRL_INTLEVEL_2_87V_2_98V ((unsigned int) 0x0000000C) +#define SCB_BODCTRL_INTLEVEL_MASK ((unsigned int) 0x0000000C) +#define SCB_BODCTRL_RSTENABLE_DISABLE ((unsigned int) 0x00000000) +#define SCB_BODCTRL_RSTENABLE_ENABLE ((unsigned int) 0x00000010) +#define SCB_BODCTRL_RSTENABLE_MASK ((unsigned int) 0x00000010) + +/* SYSTCKCAL (System tick counter calibration register) */ + +#define SCB_SYSTICKCCAL_MASK ((unsigned int) 0x03FFFFFF) // Undefined as of v0.07 of the LPC1343 User Manual + +/* STARTAPRP0 (Start logic edge control register 0) + The STARTAPRP0 register controls the start logic inputs of ports 0 (PIO0_0 to PIO0_11) + and 1 (PIO1_0 to PIO1_11) and the lower 8 inputs of port 2 (PIO2_0 to PIO2_7). This + register selects a falling or rising edge on the corresponding PIO input to produce a falling + or rising clock edge, respectively, for the start logic (see Section 3–9.3). + Every bit in the STARTAPRP0 register controls one port input and is connected to one + wake-up interrupt in the NVIC. Bit 0 in the STARTAPRP0 register corresponds to interrupt + 0, bit 1 to interrupt 1, etc.. The bottom 32 interrupts are contained this register, + the top 8 interrupts are contained in the STARTAPRP1 register for total of 40 wake-up + interrupts. + Remark: Each interrupt connected to a start logic input must be enabled in the NVIC if the + corresponding PIO pin is used to wake up the chip from Deep-sleep mode. */ + +#define SCB_STARTAPRP0_APRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP0_APRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTAPRP0_APRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTAPRP0_APRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTAPRP0_APRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTAPRP0_APRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTAPRP0_APRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTAPRP0_APRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTAPRP0_APRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTAPRP0_APRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTAPRP0_APRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTAPRP0_APRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTAPRP0_APRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTAPRP0_APRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTAPRP0_APRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTAPRP0_APRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTAPRP0_APRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTAPRP0_APRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTAPRP0_APRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTAPRP0_APRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTAPRP0_APRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTAPRP0_APRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTAPRP0_APRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTAPRP0_APRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTAPRP0_APRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTAPRP0_APRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTAPRP0_APRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTAPRP0_APRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTAPRP0_APRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTAPRP0_APRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTAPRP0_APRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTAPRP0_APRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTAPRP0_APRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTAPRP0_APRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTAPRP0_APRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTAPRP0_APRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTAPRP0_APRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTAPRP0_APRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTAPRP0_APRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTAPRP0_APRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTAPRP0_APRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTAPRP0_APRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTAPRP0_APRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTAPRP0_APRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTAPRP0_APRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTAPRP0_APRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTAPRP0_APRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTAPRP0_APRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTAPRP0_APRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTAPRP0_APRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTAPRP0_APRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTAPRP0_APRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTAPRP0_APRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTAPRP0_APRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTAPRP0_APRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTAPRP0_APRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTAPRP0_APRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTAPRP0_APRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTAPRP0_APRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTAPRP0_APRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTAPRP0_APRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTAPRP0_APRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTAPRP0_APRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTAPRP0_APRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTAPRP0_MASK ((unsigned int) 0xFFFFFFFF) + +/* STARTERP0 (Start logic signal enable register 0) + This STARTERP0 register enables or disables the start signal bits in the start logic. */ + +#define SCB_STARTERP0_ERPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTERP0_ERPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTERP0_ERPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTERP0_ERPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTERP0_ERPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTERP0_ERPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTERP0_ERPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTERP0_ERPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTERP0_ERPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTERP0_ERPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTERP0_ERPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTERP0_ERPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTERP0_ERPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTERP0_ERPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTERP0_ERPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTERP0_ERPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTERP0_ERPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTERP0_ERPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTERP0_ERPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTERP0_ERPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTERP0_ERPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTERP0_ERPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTERP0_ERPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTERP0_ERPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTERP0_ERPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTERP0_ERPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTERP0_ERPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTERP0_ERPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTERP0_ERPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTERP0_ERPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTERP0_ERPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTERP0_ERPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTERP0_ERPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTERP0_ERPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTERP0_ERPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTERP0_ERPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTERP0_ERPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTERP0_ERPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTERP0_ERPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTERP0_ERPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTERP0_ERPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTERP0_ERPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTERP0_ERPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTERP0_ERPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTERP0_ERPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTERP0_ERPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTERP0_ERPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTERP0_ERPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTERP0_ERPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTERP0_ERPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTERP0_ERPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTERP0_ERPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTERP0_ERPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTERP0_ERPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTERP0_ERPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTERP0_ERPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTERP0_ERPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTERP0_ERPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTERP0_ERPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTERP0_ERPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTERP0_ERPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTERP0_ERPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTERP0_ERPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTERP0_ERPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTERP0_MASK ((unsigned int) 0xFFFFFFFF) + +/* STARTRSRP0CLR (Start logic reset register 0) + Writing a one to a bit in the STARTRSRP0CLR register resets the start logic state. The + start-up logic uses the input signals to generate a clock edge for registering a start + signal. This clock edge (falling or rising) sets the interrupt for waking up from + Deep-sleep mode. Therefore, the start-up logic states must be cleared before being used. */ + +#define SCB_STARTRSRP0CLR_RSRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP0CLR_RSRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTRSRP0CLR_RSRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTRSRP0CLR_RSRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTRSRP0CLR_RSRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTRSRP0CLR_RSRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTRSRP0CLR_RSRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTRSRP0CLR_RSRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTRSRP0CLR_RSRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTRSRP0CLR_RSRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTRSRP0CLR_RSRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTRSRP0CLR_RSRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTRSRP0CLR_RSRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTRSRP0CLR_RSRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTRSRP0CLR_RSRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTRSRP0CLR_RSRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTRSRP0CLR_RSRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTRSRP0CLR_RSRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTRSRP0CLR_RSRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTRSRP0CLR_RSRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTRSRP0CLR_RSRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTRSRP0CLR_RSRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTRSRP0CLR_RSRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTRSRP0CLR_RSRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTRSRP0CLR_RSRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTRSRP0CLR_RSRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTRSRP0CLR_RSRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTRSRP0CLR_RSRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTRSRP0CLR_RSRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTRSRP0CLR_RSRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTRSRP0CLR_RSRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTRSRP0CLR_RSRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTRSRP0CLR_RSRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTRSRP0CLR_RSRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTRSRP0CLR_RSRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTRSRP0CLR_RSRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTRSRP0CLR_RSRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTRSRP0CLR_RSRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTRSRP0CLR_RSRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTRSRP0CLR_RSRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTRSRP0CLR_RSRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTRSRP0CLR_RSRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTRSRP0CLR_RSRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTRSRP0CLR_RSRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTRSRP0CLR_RSRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTRSRP0CLR_RSRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTRSRP0CLR_RSRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTRSRP0CLR_RSRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTRSRP0CLR_RSRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTRSRP0CLR_RSRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTRSRP0CLR_MASK ((unsigned int) 0xFFFFFFFF) + +/* (Start logic status register 0) + This register reflects the status of the enabled start signal bits. Each bit + (if enabled) reflects the state of the start logic, i.e. whether or not a + wake-up signal has been received for a given pin. */ + +#define SCB_STARTSRP0_SRPIO0_0 ((unsigned int) 0x00000001) +#define SCB_STARTSRP0_SRPIO0_0_MASK ((unsigned int) 0x00000001) +#define SCB_STARTSRP0_SRPIO0_1 ((unsigned int) 0x00000002) +#define SCB_STARTSRP0_SRPIO0_1_MASK ((unsigned int) 0x00000002) +#define SCB_STARTSRP0_SRPIO0_2 ((unsigned int) 0x00000004) +#define SCB_STARTSRP0_SRPIO0_2_MASK ((unsigned int) 0x00000004) +#define SCB_STARTSRP0_SRPIO0_3 ((unsigned int) 0x00000008) +#define SCB_STARTSRP0_SRPIO0_3_MASK ((unsigned int) 0x00000008) +#define SCB_STARTSRP0_SRPIO0_4 ((unsigned int) 0x00000010) +#define SCB_STARTSRP0_SRPIO0_4_MASK ((unsigned int) 0x00000010) +#define SCB_STARTSRP0_SRPIO0_5 ((unsigned int) 0x00000020) +#define SCB_STARTSRP0_SRPIO0_5_MASK ((unsigned int) 0x00000020) +#define SCB_STARTSRP0_SRPIO0_6 ((unsigned int) 0x00000040) +#define SCB_STARTSRP0_SRPIO0_6_MASK ((unsigned int) 0x00000040) +#define SCB_STARTSRP0_SRPIO0_7 ((unsigned int) 0x00000080) +#define SCB_STARTSRP0_SRPIO0_7_MASK ((unsigned int) 0x00000080) +#define SCB_STARTSRP0_SRPIO0_8 ((unsigned int) 0x00000100) +#define SCB_STARTSRP0_SRPIO0_8_MASK ((unsigned int) 0x00000100) +#define SCB_STARTSRP0_SRPIO0_9 ((unsigned int) 0x00000200) +#define SCB_STARTSRP0_SRPIO0_9_MASK ((unsigned int) 0x00000200) +#define SCB_STARTSRP0_SRPIO0_10 ((unsigned int) 0x00000400) +#define SCB_STARTSRP0_SRPIO0_10_MASK ((unsigned int) 0x00000400) +#define SCB_STARTSRP0_SRPIO0_11 ((unsigned int) 0x00000800) +#define SCB_STARTSRP0_SRPIO0_11_MASK ((unsigned int) 0x00000800) +#define SCB_STARTSRP0_SRPIO1_0 ((unsigned int) 0x00001000) +#define SCB_STARTSRP0_SRPIO1_0_MASK ((unsigned int) 0x00001000) +#define SCB_STARTSRP0_SRPIO1_1 ((unsigned int) 0x00002000) +#define SCB_STARTSRP0_SRPIO1_1_MASK ((unsigned int) 0x00002000) +#define SCB_STARTSRP0_SRPIO1_2 ((unsigned int) 0x00004000) +#define SCB_STARTSRP0_SRPIO1_2_MASK ((unsigned int) 0x00004000) +#define SCB_STARTSRP0_SRPIO1_3 ((unsigned int) 0x00008000) +#define SCB_STARTSRP0_SRPIO1_3_MASK ((unsigned int) 0x00008000) +#define SCB_STARTSRP0_SRPIO1_4 ((unsigned int) 0x00010000) +#define SCB_STARTSRP0_SRPIO1_4_MASK ((unsigned int) 0x00010000) +#define SCB_STARTSRP0_SRPIO1_5 ((unsigned int) 0x00020000) +#define SCB_STARTSRP0_SRPIO1_5_MASK ((unsigned int) 0x00020000) +#define SCB_STARTSRP0_SRPIO1_6 ((unsigned int) 0x00040000) +#define SCB_STARTSRP0_SRPIO1_6_MASK ((unsigned int) 0x00040000) +#define SCB_STARTSRP0_SRPIO1_7 ((unsigned int) 0x00080000) +#define SCB_STARTSRP0_SRPIO1_7_MASK ((unsigned int) 0x00080000) +#define SCB_STARTSRP0_SRPIO1_8 ((unsigned int) 0x00100000) +#define SCB_STARTSRP0_SRPIO1_8_MASK ((unsigned int) 0x00100000) +#define SCB_STARTSRP0_SRPIO1_9 ((unsigned int) 0x00200000) +#define SCB_STARTSRP0_SRPIO1_9_MASK ((unsigned int) 0x00200000) +#define SCB_STARTSRP0_SRPIO1_10 ((unsigned int) 0x00400000) +#define SCB_STARTSRP0_SRPIO1_10_MASK ((unsigned int) 0x00400000) +#define SCB_STARTSRP0_SRPIO1_11 ((unsigned int) 0x00800000) +#define SCB_STARTSRP0_SRPIO1_11_MASK ((unsigned int) 0x00800000) +#define SCB_STARTSRP0_SRPIO2_0 ((unsigned int) 0x01000000) +#define SCB_STARTSRP0_SRPIO2_0_MASK ((unsigned int) 0x01000000) +#define SCB_STARTSRP0_SRPIO2_1 ((unsigned int) 0x02000000) +#define SCB_STARTSRP0_SRPIO2_1_MASK ((unsigned int) 0x02000000) +#define SCB_STARTSRP0_SRPIO2_2 ((unsigned int) 0x04000000) +#define SCB_STARTSRP0_SRPIO2_2_MASK ((unsigned int) 0x04000000) +#define SCB_STARTSRP0_SRPIO2_3 ((unsigned int) 0x08000000) +#define SCB_STARTSRP0_SRPIO2_3_MASK ((unsigned int) 0x08000000) +#define SCB_STARTSRP0_SRPIO2_4 ((unsigned int) 0x10000000) +#define SCB_STARTSRP0_SRPIO2_4_MASK ((unsigned int) 0x10000000) +#define SCB_STARTSRP0_SRPIO2_5 ((unsigned int) 0x20000000) +#define SCB_STARTSRP0_SRPIO2_5_MASK ((unsigned int) 0x20000000) +#define SCB_STARTSRP0_SRPIO2_6 ((unsigned int) 0x40000000) +#define SCB_STARTSRP0_SRPIO2_6_MASK ((unsigned int) 0x40000000) +#define SCB_STARTSRP0_SRPIO2_7 ((unsigned int) 0x80000000) +#define SCB_STARTSRP0_SRPIO2_7_MASK ((unsigned int) 0x80000000) +#define SCB_STARTSRP0_MASK ((unsigned int) 0xFFFFFFFF) + + +/* STARTAPRP1 (Start logic edge control register 1) + The STARTAPRP1 register controls the start logic inputs of ports 2 (PIO2_8 to PIO2_11) + and 3 (PIO3_0 to PIO3_3). This register selects a falling or rising edge on the + corresponding PIO input to produce a falling or rising clock edge, respectively, for the + start-up logic. + Every bit in the STARTAPRP1 register controls one port input and is connected to one + wake-up interrupt in the NVIC. Bit 0 in the STARTAPRP1 register corresponds to interrupt + 32, bit 1 to interrupt 33, up to bit 7 corresponding to interrupt 39. + Remark: Each interrupt connected to a start logic input must be enabled in the NVIC if the + corresponding PIO pin is used to wake up the chip from Deep-sleep mode.*/ + +#define SCB_STARTAPRP1_APRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTAPRP1_APRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTAPRP1_APRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTAPRP1_APRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTAPRP1_APRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTAPRP1_APRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTAPRP1_APRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTAPRP1_APRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTAPRP1_APRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTAPRP1_APRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTAPRP1_APRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTAPRP1_APRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTAPRP1_APRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTAPRP1_APRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTAPRP1_MASK ((unsigned int) 0x000000FF) + +/* STARTERP1 (Start logic signal enable register 1) + This STARTERP1 register enables or disables the start signal bits in the start logic. */ + +#define SCB_STARTERP1_ERPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTERP1_ERPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTERP1_ERPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTERP1_ERPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTERP1_ERPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTERP1_ERPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTERP1_ERPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTERP1_ERPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTERP1_ERPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTERP1_ERPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTERP1_ERPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTERP1_ERPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTERP1_ERPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTERP1_ERPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTERP1_MASK ((unsigned int) 0x000000FF) + +/* (Start logic reset register 1) + Writing a one to a bit in the STARTRSRP1CLR register resets the start logic state. The + start-up logic uses the input signals to generate a clock edge for registering a start + signal. This clock edge (falling or rising) sets the interrupt for waking up from + Deep-sleep mode. Therefore, the start-up logic states must be cleared before being used. */ + +#define SCB_STARTRSRP1CLR_RSRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTRSRP1CLR_RSRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTRSRP1CLR_RSRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTRSRP1CLR_RSRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTRSRP1CLR_RSRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTRSRP1CLR_RSRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTRSRP1CLR_RSRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTRSRP1CLR_RSRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTRSRP1CLR_RSRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTRSRP1CLR_RSRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTRSRP1CLR_RSRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTRSRP1CLR_RSRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTRSRP1CLR_RSRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTRSRP1CLR_RSRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTRSRP1CLR_MASK ((unsigned int) 0x000000FF) + +/* STARTSRP1 (Start logic status register 1) + This register reflects the status of the enabled start signals. */ + +#define SCB_STARTSRP1_SRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_8_MASK ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_8 ((unsigned int) 0x00000001) +#define SCB_STARTSRP1_SRPIO2_9_MASK ((unsigned int) 0x00000002) +#define SCB_STARTSRP1_SRPIO2_10 ((unsigned int) 0x00000004) +#define SCB_STARTSRP1_SRPIO2_10_MASK ((unsigned int) 0x00000004) +#define SCB_STARTSRP1_SRPIO2_11 ((unsigned int) 0x00000008) +#define SCB_STARTSRP1_SRPIO2_11_MASK ((unsigned int) 0x00000008) +#define SCB_STARTSRP1_SRPIO3_0 ((unsigned int) 0x00000010) +#define SCB_STARTSRP1_SRPIO3_0_MASK ((unsigned int) 0x00000010) +#define SCB_STARTSRP1_SRPIO3_1 ((unsigned int) 0x00000020) +#define SCB_STARTSRP1_SRPIO3_1_MASK ((unsigned int) 0x00000020) +#define SCB_STARTSRP1_SRPIO3_2 ((unsigned int) 0x00000040) +#define SCB_STARTSRP1_SRPIO3_2_MASK ((unsigned int) 0x00000040) +#define SCB_STARTSRP1_SRPIO3_3 ((unsigned int) 0x00000080) +#define SCB_STARTSRP1_SRPIO3_3_MASK ((unsigned int) 0x00000080) +#define SCB_STARTSRP1_MASK ((unsigned int) 0x000000FF) + +/* PDSLEEPCFG (Deep-sleep mode configuration register) + The bits in this register can be programmed to indicate the state the chip must enter when + the Deep-sleep mode is asserted by the ARM. The value of the PDSLEEPCFG register + will be automatically loaded into the PDRUNCFG register when the Sleep mode is + entered. */ + +#define SCB_PDSLEEPCFG_IRCOUT_PD ((unsigned int) 0x00000001) +#define SCB_PDSLEEPCFG_IRCOUT_PD_MASK ((unsigned int) 0x00000001) +#define SCB_PDSLEEPCFG_IRC_PD ((unsigned int) 0x00000002) +#define SCB_PDSLEEPCFG_IRC_PD_MASK ((unsigned int) 0x00000002) +#define SCB_PDSLEEPCFG_FLASH_PD ((unsigned int) 0x00000004) +#define SCB_PDSLEEPCFG_FLASH_PD_MASK ((unsigned int) 0x00000004) +#define SCB_PDSLEEPCFG_BOD_PD ((unsigned int) 0x00000008) +#define SCB_PDSLEEPCFG_BOD_PD_MASK ((unsigned int) 0x00000008) +#define SCB_PDSLEEPCFG_ADC_PD ((unsigned int) 0x00000010) +#define SCB_PDSLEEPCFG_ADC_PD_MASK ((unsigned int) 0x00000010) +#define SCB_PDSLEEPCFG_SYSOSC_PD ((unsigned int) 0x00000020) +#define SCB_PDSLEEPCFG_SYSOSC_PD_MASK ((unsigned int) 0x00000020) +#define SCB_PDSLEEPCFG_WDTOSC_PD ((unsigned int) 0x00000040) +#define SCB_PDSLEEPCFG_WDTOSC_PD_MASK ((unsigned int) 0x00000040) +#define SCB_PDSLEEPCFG_SYSPLL_PD ((unsigned int) 0x00000080) +#define SCB_PDSLEEPCFG_SYSPLL_PD_MASK ((unsigned int) 0x00000080) +#define SCB_PDSLEEPCFG_USBPLL_PD ((unsigned int) 0x00000100) +#define SCB_PDSLEEPCFG_USBPLL_PD_MASK ((unsigned int) 0x00000100) +#define SCB_PDSLEEPCFG_USBPAD_PD ((unsigned int) 0x00000400) +#define SCB_PDSLEEPCFG_USBPAD_PD_MASK ((unsigned int) 0x00000400) + +/* PDAWAKECFG (Wake-up configuration register) + The bits in this register can be programmed to indicate the state the chip must enter when + it is waking up from Deep-sleep mode. */ + +#define SCB_PDAWAKECFG_IRCOUT_PD ((unsigned int) 0x00000001) +#define SCB_PDAWAKECFG_IRCOUT_PD_MASK ((unsigned int) 0x00000001) +#define SCB_PDAWAKECFG_IRC_PD ((unsigned int) 0x00000002) +#define SCB_PDAWAKECFG_IRC_PD_MASK ((unsigned int) 0x00000002) +#define SCB_PDAWAKECFG_FLASH_PD ((unsigned int) 0x00000004) +#define SCB_PDAWAKECFG_FLASH_PD_MASK ((unsigned int) 0x00000004) +#define SCB_PDAWAKECFG_BOD_PD ((unsigned int) 0x00000008) +#define SCB_PDAWAKECFG_BOD_PD_MASK ((unsigned int) 0x00000008) +#define SCB_PDAWAKECFG_ADC_PD ((unsigned int) 0x00000010) +#define SCB_PDAWAKECFG_ADC_PD_MASK ((unsigned int) 0x00000010) +#define SCB_PDAWAKECFG_SYSOSC_PD ((unsigned int) 0x00000020) +#define SCB_PDAWAKECFG_SYSOSC_PD_MASK ((unsigned int) 0x00000020) +#define SCB_PDAWAKECFG_WDTOSC_PD ((unsigned int) 0x00000040) +#define SCB_PDAWAKECFG_WDTOSC_PD_MASK ((unsigned int) 0x00000040) +#define SCB_PDAWAKECFG_SYSPLL_PD ((unsigned int) 0x00000080) +#define SCB_PDAWAKECFG_SYSPLL_PD_MASK ((unsigned int) 0x00000080) +#define SCB_PDAWAKECFG_USBPLL_PD ((unsigned int) 0x00000100) +#define SCB_PDAWAKECFG_USBPLL_PD_MASK ((unsigned int) 0x00000100) +#define SCB_PDAWAKECFG_USBPAD_PD ((unsigned int) 0x00000400) +#define SCB_PDAWAKECFG_USBPAD_PD_MASK ((unsigned int) 0x00000400) + +/* PDRUNCFG (Power-down configuration register) + The bits in the PDRUNCFG register control the power to the various analog blocks. This + register can be written to at any time while the chip is running, and a write will take effect + immediately with the exception of the power-down signal to the IRC. Setting a 1 powers-down + a peripheral and 0 enables it. */ + +#define SCB_PDRUNCFG_IRCOUT ((unsigned int) 0x00000001) // IRC oscillator output power-down +#define SCB_PDRUNCFG_IRCOUT_MASK ((unsigned int) 0x00000001) +#define SCB_PDRUNCFG_IRC ((unsigned int) 0x00000002) // IRC oscillator power-down +#define SCB_PDRUNCFG_IRC_MASK ((unsigned int) 0x00000002) +#define SCB_PDRUNCFG_FLASH ((unsigned int) 0x00000004) // Flash power-down +#define SCB_PDRUNCFG_FLASH_MASK ((unsigned int) 0x00000004) +#define SCB_PDRUNCFG_BOD ((unsigned int) 0x00000008) // Brown-out detector power-down +#define SCB_PDRUNCFG_BOD_MASK ((unsigned int) 0x00000008) +#define SCB_PDRUNCFG_ADC ((unsigned int) 0x00000010) // ADC power-down +#define SCB_PDRUNCFG_ADC_MASK ((unsigned int) 0x00000010) +#define SCB_PDRUNCFG_SYSOSC ((unsigned int) 0x00000020) // System oscillator power-down +#define SCB_PDRUNCFG_SYSOSC_MASK ((unsigned int) 0x00000020) +#define SCB_PDRUNCFG_WDTOSC ((unsigned int) 0x00000040) // Watchdog oscillator power-down +#define SCB_PDRUNCFG_WDTOSC_MASK ((unsigned int) 0x00000040) +#define SCB_PDRUNCFG_SYSPLL ((unsigned int) 0x00000080) // System PLL power-down +#define SCB_PDRUNCFG_SYSPLL_MASK ((unsigned int) 0x00000080) +#define SCB_PDRUNCFG_USBPLL ((unsigned int) 0x00000100) // USB PLL power-down +#define SCB_PDRUNCFG_USBPLL_MASK ((unsigned int) 0x00000100) +#define SCB_PDRUNCFG_USBPAD ((unsigned int) 0x00000400) // USB PHY power-down +#define SCB_PDRUNCFG_USBPAD_MASK ((unsigned int) 0x00000400) + +/* DEVICE_ID (Device ID Register) + This device ID register is a read-only register and contains the device ID for each + LPC13xx part. This register is also read by the ISP/IAP commands. */ + +#define SCB_DEVICEID_LPC1311FHN33 ((unsigned int) 0x2C42502B) +#define SCB_DEVICEID_LPC1313FHN33 ((unsigned int) 0x2C40102B) +#define SCB_DEVICEID_LPC1313FBD48 ((unsigned int) 0x2C40102B) +#define SCB_DEVICEID_LPC1342FHN33 ((unsigned int) 0x3D01402B) +#define SCB_DEVICEID_LPC1343FHN33 ((unsigned int) 0x3D00002B) +#define SCB_DEVICEID_LPC1343FBD48 ((unsigned int) 0x3D00002B) + +/*############################################################################## +## Data Watchpoint and Trace Unit (DWT) +##############################################################################*/ +// For more information, see Cortex-M3 Technical Reference Manual 8.3 +// This block is optional and not all comparators or functionality may +// be present on all chips, though basic DWT functionality is present +// on the LPC1343 since CYCNT works + +#define DWT_CTRL (*(pREG32 (0xE0001000))) // Control register +#define DWT_CYCCNT (*(pREG32 (0xE0001004))) // Cycle counter (useful for rough performance testing) +#define DWT_CPICNT (*(pREG32 (0xE0001008))) // CPI Count Register +#define DWT_EXCCNT (*(pREG32 (0xE000100C))) // Exception overhead count register +#define DWT_SLEEPCNT (*(pREG32 (0xE0001010))) // Sleep count register +#define DWT_LSUCNT (*(pREG32 (0xE0001014))) // LSU count register +#define DWT_FOLDCNT (*(pREG32 (0xE0001018))) // Folder-instruction count register +#define DWT_PCSR (*(pREG32 (0xE000101C))) // Program counter sample register +#define DWT_COMP0 (*(pREG32 (0xE0001020))) // Comparator register 0 +#define DWT_MASK0 (*(pREG32 (0xE0001024))) // Mask register 0 +#define DWT_FUNCTION0 (*(pREG32 (0xE0001028))) // Function register 0 +#define DWT_COMP1 (*(pREG32 (0xE0001030))) // Comparator register 1 +#define DWT_MASK1 (*(pREG32 (0xE0001034))) // Mask register 1 +#define DWT_FUNCTION1 (*(pREG32 (0xE0001038))) // Function register 1 +#define DWT_COMP2 (*(pREG32 (0xE0001040))) // Comparator register 2 +#define DWT_MASK2 (*(pREG32 (0xE0001044))) // Mask register 2 +#define DWT_FUNCTION2 (*(pREG32 (0xE0001048))) // Function register 2 +#define DWT_COMP3 (*(pREG32 (0xE0001050))) // Comparator register 3 +#define DWT_MASK3 (*(pREG32 (0xE0001054))) // Mask register 3 +#define DWT_FUNCTION3 (*(pREG32 (0xE0001058))) // Function register 3 + +/*############################################################################## +## Power Management Unit (PMU) +##############################################################################*/ + +#define PMU_BASE_ADDRESS (0x40038000) + +#define PMU_PMUCTRL (*(pREG32 (0x40038000))) // Power control register +#define PMU_GPREG0 (*(pREG32 (0x40038004))) // General purpose register 0 +#define PMU_GPREG1 (*(pREG32 (0x40038008))) // General purpose register 1 +#define PMU_GPREG2 (*(pREG32 (0x4003800C))) // General purpose register 2 +#define PMU_GPREG3 (*(pREG32 (0x40038010))) // General purpose register 3 +#define PMU_GPREG4 (*(pREG32 (0x40038014))) // General purpose register 4 + +#define PMU_PMUCTRL_DPDEN_MASK ((unsigned int) 0x00000002) // Deep power-down enable +#define PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN ((unsigned int) 0x00000002) // WFI will enter deep power-down mode +#define PMU_PMUCTRL_DPDEN_SLEEP ((unsigned int) 0x00000000) // WFI will enter sleep mode +#define PMU_PMUCTRL_DPDFLAG_MASK ((unsigned int) 0x00000800) // Deep power-down flag +#define PMU_PMUCTRL_DPDFLAG ((unsigned int) 0x00000800) + +/* GPREG0..3 (General purpose registers 0 to 3) + The general purpose registers retain data through the Deep power-down mode when + power is still applied to the VDD(3V3) pin but the chip has entered Deep power-down mode. + Only a “cold” boot when all power has been completely removed from the chip will reset + the general purpose registers. */ + +#define PMU_GPREG0_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG1_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG2_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) +#define PMU_GPREG3_GPDATA_MASK ((unsigned int) 0xFFFFFFFF) + +/* GPREG4 (General purpose register 4) + The general purpose register 4 retains data through the Deep power-down mode when + power is still applied to the VDD(3V3) pin but the chip has entered Deep power-down mode. + Only a “cold” boot, when all power has been completely removed from the chip, will reset + the general purpose registers. + + Remark: If the external voltage applied on pin VDD(3V3) drops below V, the + hysteresis of the WAKEUP input pin has to be disabled in order for the chip to wake up + from Deep power-down mode. */ + +#define PMU_GPREG4_GPDATA_MASK ((unsigned int) 0xFFFFF800) +#define PMU_GPREG4_WAKEUPHYS_MASK ((unsigned int) 0x00000400) +#define PMU_GPREG4_WAKEUPHYS_HYSTERESISENABLED ((unsigned int) 0x00000400) +#define PMU_GPREG4_WAKEUPHYS_HYSTERESISDISABLED ((unsigned int) 0x00000000) +#define PMU_GPREG4_GPDATA_MASK ((unsigned int) 0xFFFFF800) + +/*############################################################################## +## I/O Control (IOCON) +##############################################################################*/ + +#define IOCON_BASE_ADDRESS (0x40044000) + +/* Values that should be common to all pins, though they are also defined + on the individual pin level in case they change with a pin on any future + device */ + +#define IOCON_COMMON_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_COMMON_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_COMMON_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_COMMON_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_COMMON_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_COMMON_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_COMMON_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_COMMON_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_COMMON_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_6 (*(pREG32 (0x40044000))) +#define IOCON_PIO2_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_6_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_0 (*(pREG32 (0x40044008))) +#define IOCON_PIO2_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_0_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_FUNC_DTR ((unsigned int) 0x00000001) +#define IOCON_PIO2_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_nRESET_PIO0_0 (*(pREG32 (0x4004400C))) +#define IOCON_nRESET_PIO0_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_nRESET_PIO0_0_FUNC_RESET ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_nRESET_PIO0_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_nRESET_PIO0_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_nRESET_PIO0_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_nRESET_PIO0_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_nRESET_PIO0_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_nRESET_PIO0_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_nRESET_PIO0_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_1 (*(pREG32 (0x40044010))) +#define IOCON_PIO0_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_FUNC_CLKOUT ((unsigned int) 0x00000001) +#define IOCON_PIO0_1_FUNC_CT32B0_MAT2 ((unsigned int) 0x00000002) +#define IOCON_PIO0_1_FUNC_USB_FTOGGLE ((unsigned int) 0x00000003) +#define IOCON_PIO0_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_8 (*(pREG32 (0x40044014))) +#define IOCON_PIO1_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_FUNC_CT16B1_CAP0 ((unsigned int) 0x00000001) +#define IOCON_PIO1_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_2 (*(pREG32 (0x4004401C))) +#define IOCON_PIO0_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_FUNC_SSEL ((unsigned int) 0x00000001) +#define IOCON_PIO0_2_FUNC_CT16B0_CAP0 ((unsigned int) 0x00000002) +#define IOCON_PIO0_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_7 (*(pREG32 (0x40044020))) +#define IOCON_PIO2_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_8 (*(pREG32 (0x40044024))) +#define IOCON_PIO2_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_1 (*(pREG32 (0x40044028))) +#define IOCON_PIO2_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_FUNC_DSR ((unsigned int) 0x00000001) +#define IOCON_PIO2_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_3 (*(pREG32 (0x4004402C))) +#define IOCON_PIO0_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_3_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_FUNC_USB_VBUS ((unsigned int) 0x00000001) +#define IOCON_PIO0_3_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_3_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_3_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_3_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_3_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_4 (*(pREG32 (0x40044030))) +#define IOCON_PIO0_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_4_FUNC_I2CSCL ((unsigned int) 0x00000001) +#define IOCON_PIO0_4_I2CMODE_MASK ((unsigned int) 0x00000300) +#define IOCON_PIO0_4_I2CMODE_STANDARDI2C ((unsigned int) 0x00000000) +#define IOCON_PIO0_4_I2CMODE_STANDARDIO ((unsigned int) 0x00000100) +#define IOCON_PIO0_4_I2CMODE_FASTPLUSI2C ((unsigned int) 0x00000200) + +#define IOCON_PIO0_5 (*(pREG32 (0x40044034))) +#define IOCON_PIO0_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_5_FUNC_I2CSDA ((unsigned int) 0x00000001) +#define IOCON_PIO0_5_I2CMODE_MASK ((unsigned int) 0x00000300) +#define IOCON_PIO0_5_I2CMODE_STANDARDI2C ((unsigned int) 0x00000000) +#define IOCON_PIO0_5_I2CMODE_STANDARDIO ((unsigned int) 0x00000100) +#define IOCON_PIO0_5_I2CMODE_FASTPLUSI2C ((unsigned int) 0x00000200) + +#define IOCON_PIO1_9 (*(pREG32 (0x40044038))) +#define IOCON_PIO1_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_FUNC_CT16B1_MAT0 ((unsigned int) 0x00000001) +#define IOCON_PIO1_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_4 (*(pREG32 (0x4004403C))) +#define IOCON_PIO3_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_4_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_4 (*(pREG32 (0x40044040))) +#define IOCON_PIO2_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_4_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_5 (*(pREG32 (0x40044044))) +#define IOCON_PIO2_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_5 (*(pREG32 (0x40044048))) +#define IOCON_PIO3_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_6 (*(pREG32 (0x4004404C))) +#define IOCON_PIO0_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_FUNC_USB_CONNECT ((unsigned int) 0x00000001) +#define IOCON_PIO0_6_FUNC_SCK ((unsigned int) 0x00000002) +#define IOCON_PIO0_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_6_HYS_ENABLE ((unsigned int) 0x00000020) + + +#define IOCON_PIO0_7 (*(pREG32 (0x40044050))) +#define IOCON_PIO0_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_FUNC_CTS ((unsigned int) 0x00000001) +#define IOCON_PIO0_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_9 (*(pREG32 (0x40044054))) +#define IOCON_PIO2_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_10 (*(pREG32 (0x40044058))) +#define IOCON_PIO2_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_10_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_10_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_2 (*(pREG32 (0x4004405C))) +#define IOCON_PIO2_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_FUNC_DCD ((unsigned int) 0x00000001) +#define IOCON_PIO2_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_8 (*(pREG32 (0x40044060))) +#define IOCON_PIO0_8_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_8_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_FUNC_MISO0 ((unsigned int) 0x00000001) +#define IOCON_PIO0_8_FUNC_CT16B0_MAT0 ((unsigned int) 0x00000002) +#define IOCON_PIO0_8_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_8_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_8_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_8_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_8_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_8_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_8_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO0_9 (*(pREG32 (0x40044064))) +#define IOCON_PIO0_9_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO0_9_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_FUNC_MOSI0 ((unsigned int) 0x00000001) +#define IOCON_PIO0_9_FUNC_CT16B0_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO0_9_FUNC_SWO ((unsigned int) 0x00000003) +#define IOCON_PIO0_9_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO0_9_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO0_9_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO0_9_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO0_9_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO0_9_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO0_9_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_JTAG_TCK_PIO0_10 (*(pREG32 (0x40044068))) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_SWCLK ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_SCK ((unsigned int) 0x00000002) +#define IOCON_JTAG_TCK_PIO0_10_FUNC_CT16B0_MAT2 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TCK_PIO0_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TCK_PIO0_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TCK_PIO0_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TCK_PIO0_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TCK_PIO0_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TCK_PIO0_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TCK_PIO0_10_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_10 (*(pREG32 (0x4004406C))) +#define IOCON_PIO1_10_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_10_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_FUNC_AD6 ((unsigned int) 0x00000001) +#define IOCON_PIO1_10_FUNC_CT16B1_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO1_10_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_10_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_10_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_10_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_10_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_10_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_10_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_10_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_10_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO2_11 (*(pREG32 (0x40044070))) +#define IOCON_PIO2_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO2_11_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_FUNC_SCK0 ((unsigned int) 0x00000001) +#define IOCON_PIO2_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO2_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO2_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO2_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO2_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO2_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO2_11_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_JTAG_TDI_PIO0_11 (*(pREG32 (0x40044074))) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_TDI ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_AD0 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TDI_PIO0_11_FUNC_CT32B0_MAT3 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TDI_PIO0_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDI_PIO0_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TDI_PIO0_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TDI_PIO0_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDI_PIO0_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDI_PIO0_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDI_PIO0_11_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_TMS_PIO1_0 (*(pREG32 (0x40044078))) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_TMS ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_AD1 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TMS_PIO1_0_FUNC_CT32B1_CAP0 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TMS_PIO1_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TMS_PIO1_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TMS_PIO1_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TMS_PIO1_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TMS_PIO1_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TMS_PIO1_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TMS_PIO1_0_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_TDO_PIO1_1 (*(pREG32 (0x4004407C))) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_TDO ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_AD2 ((unsigned int) 0x00000002) +#define IOCON_JTAG_TDO_PIO1_1_FUNC_CT32B1_MAT0 ((unsigned int) 0x00000003) +#define IOCON_JTAG_TDO_PIO1_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDO_PIO1_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_TDO_PIO1_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_TDO_PIO1_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_TDO_PIO1_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDO_PIO1_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_TDO_PIO1_1_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_JTAG_nTRST_PIO1_2 (*(pREG32 (0x40044080))) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_TRST ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3 ((unsigned int) 0x00000002) +#define IOCON_JTAG_nTRST_PIO1_2_FUNC_CT32B1_MAT1 ((unsigned int) 0x00000003) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_JTAG_nTRST_PIO1_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_JTAG_nTRST_PIO1_2_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO3_0 (*(pREG32 (0x40044084))) +#define IOCON_PIO3_0_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_0_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_0_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_0_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_0_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_0_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_0_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_0_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_1 (*(pREG32 (0x40044088))) +#define IOCON_PIO3_1_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_1_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_1_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_1_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_1_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_1_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_1_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_1_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO2_3 (*(pREG32 (0x4004408C))) +#define IOCON_PIO2_3_FUNC_MASK 0x7 +#define IOCON_PIO2_3_MODE_MASK 0x18 +#define IOCON_PIO2_3_HYS_MASK 0x20 +#define IOCON_PIO2_3_HYS 0x20 + +#define IOCON_SWDIO_PIO1_3 (*(pREG32 (0x40044090))) +#define IOCON_SWDIO_PIO1_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_SWDIO_PIO1_3_FUNC_SWDIO ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_FUNC_GPIO ((unsigned int) 0x00000001) +#define IOCON_SWDIO_PIO1_3_FUNC_AD4 ((unsigned int) 0x00000002) +#define IOCON_SWDIO_PIO1_3_FUNC_CT32B1_MAT2 ((unsigned int) 0x00000004) +#define IOCON_SWDIO_PIO1_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_SWDIO_PIO1_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_SWDIO_PIO1_3_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_SWDIO_PIO1_3_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_SWDIO_PIO1_3_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO1_4 (*(pREG32 (0x40044094))) +#define IOCON_PIO1_4_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_4_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_FUNC_AD5 ((unsigned int) 0x00000001) +#define IOCON_PIO1_4_FUNC_CT32B1_MAT3 ((unsigned int) 0x00000002) +#define IOCON_PIO1_4_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_4_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_4_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_4_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_4_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_4_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_4_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_4_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_4_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO1_11 (*(pREG32 (0x40044098))) +#define IOCON_PIO1_11_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_11_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_FUNC_AD7 ((unsigned int) 0x00000001) +#define IOCON_PIO1_11_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_11_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_11_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_11_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_11_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_11_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_HYS_ENABLE ((unsigned int) 0x00000020) +#define IOCON_PIO1_11_ADMODE_MASK ((unsigned int) 0x00000080) +#define IOCON_PIO1_11_ADMODE_ANALOG ((unsigned int) 0x00000000) +#define IOCON_PIO1_11_ADMODE_DIGITAL ((unsigned int) 0x00000080) + +#define IOCON_PIO3_2 (*(pREG32 (0x4004409C))) +#define IOCON_PIO3_2_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_2_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_2_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_2_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_2_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_2_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_2_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_2_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_5 (*(pREG32 (0x400440A0))) +#define IOCON_PIO1_5_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_5_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_FUNC_RTS ((unsigned int) 0x00000001) +#define IOCON_PIO1_5_FUNC_CT32B0_CAP0 ((unsigned int) 0x00000002) +#define IOCON_PIO1_5_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_5_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_5_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_5_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_5_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_5_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_5_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_6 (*(pREG32 (0x400440A4))) +#define IOCON_PIO1_6_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_6_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_FUNC_UART_RXD ((unsigned int) 0x00000001) +#define IOCON_PIO1_6_FUNC_CT32B0_MAT0 ((unsigned int) 0x00000002) +#define IOCON_PIO1_6_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_6_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_6_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_6_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_6_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_6_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_6_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO1_7 (*(pREG32 (0x400440A8))) +#define IOCON_PIO1_7_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO1_7_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_FUNC_UART_TXD ((unsigned int) 0x00000001) +#define IOCON_PIO1_7_FUNC_CT32B0_MAT1 ((unsigned int) 0x00000002) +#define IOCON_PIO1_7_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO1_7_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO1_7_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO1_7_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO1_7_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO1_7_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO1_7_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_PIO3_3 (*(pREG32 (0x400440AC))) +#define IOCON_PIO3_3_FUNC_MASK ((unsigned int) 0x00000007) +#define IOCON_PIO3_3_FUNC_GPIO ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_MODE_MASK ((unsigned int) 0x00000018) +#define IOCON_PIO3_3_MODE_INACTIVE ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_MODE_PULLDOWN ((unsigned int) 0x00000008) +#define IOCON_PIO3_3_MODE_PULLUP ((unsigned int) 0x00000010) +#define IOCON_PIO3_3_MODE_REPEATER ((unsigned int) 0x00000018) +#define IOCON_PIO3_3_HYS_MASK ((unsigned int) 0x00000020) +#define IOCON_PIO3_3_HYS_DISABLE ((unsigned int) 0x00000000) +#define IOCON_PIO3_3_HYS_ENABLE ((unsigned int) 0x00000020) + +#define IOCON_SCKLOC (*(pREG32 (0x400440B0))) +#define IOCON_SCKLOC_SCKPIN_MASK ((unsigned int) 0x00000003) +#define IOCON_SCKLOC_SCKPIN_PIO0_10 ((unsigned int) 0x00000000) // Set SCK function to pin 0.10 +#define IOCON_SCKLOC_SCKPIN_PIO2_11 ((unsigned int) 0x00000001) // Set SCK function to pin 2.11 +#define IOCON_SCKLOC_SCKPIN_PIO0_6 ((unsigned int) 0x00000003) // Set SCK function to pin 0.6 + +/*############################################################################## +## Nested Vectored Interrupt Controller +##############################################################################*/ + +#define NVIC_BASE_ADDRESS (0xE000E100) + +typedef struct +{ + volatile uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + volatile uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + volatile uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + volatile uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + volatile uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + volatile uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + volatile uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ +} NVIC_Type; + +#define NVIC ((NVIC_Type *) NVIC_BASE_ADDRESS) + +static inline void __enable_irq() { __asm volatile ("cpsie i"); } +static inline void __disable_irq() { __asm volatile ("cpsid i"); } + +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** LPC13xx Specific Interrupt Numbers *******************************************************/ + WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */ + WAKEUP1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */ + WAKEUP2_IRQn = 2, + WAKEUP3_IRQn = 3, + WAKEUP4_IRQn = 4, + WAKEUP5_IRQn = 5, + WAKEUP6_IRQn = 6, + WAKEUP7_IRQn = 7, + WAKEUP8_IRQn = 8, + WAKEUP9_IRQn = 9, + WAKEUP10_IRQn = 10, + WAKEUP11_IRQn = 11, + WAKEUP12_IRQn = 12, + WAKEUP13_IRQn = 13, + WAKEUP14_IRQn = 14, + WAKEUP15_IRQn = 15, + WAKEUP16_IRQn = 16, + WAKEUP17_IRQn = 17, + WAKEUP18_IRQn = 18, + WAKEUP19_IRQn = 19, + WAKEUP20_IRQn = 20, + WAKEUP21_IRQn = 21, + WAKEUP22_IRQn = 22, + WAKEUP23_IRQn = 23, + WAKEUP24_IRQn = 24, + WAKEUP25_IRQn = 25, + WAKEUP26_IRQn = 26, + WAKEUP27_IRQn = 27, + WAKEUP28_IRQn = 28, + WAKEUP29_IRQn = 29, + WAKEUP30_IRQn = 30, + WAKEUP31_IRQn = 31, + WAKEUP32_IRQn = 32, + WAKEUP33_IRQn = 33, + WAKEUP34_IRQn = 34, + WAKEUP35_IRQn = 35, + WAKEUP36_IRQn = 36, + WAKEUP37_IRQn = 37, + WAKEUP38_IRQn = 38, + WAKEUP39_IRQn = 39, + I2C_IRQn = 40, /*!< I2C Interrupt */ + TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */ + TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */ + TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */ + TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */ + SSP_IRQn = 45, /*!< SSP Interrupt */ + UART_IRQn = 46, /*!< UART Interrupt */ + USB_IRQn = 47, /*!< USB Regular Interrupt */ + USB_FIQn = 48, /*!< USB Fast Interrupt */ + ADC_IRQn = 49, /*!< A/D Converter Interrupt */ + WDT_IRQn = 50, /*!< Watchdog timer Interrupt */ + BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */ + EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */ + EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */ + EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */ + EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */ +} IRQn_t; + +static inline void NVIC_EnableIRQ(IRQn_t IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +static inline void NVIC_DisableIRQ(IRQn_t IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/*############################################################################## +## GPIO - General Purpose I/O +##############################################################################*/ + +#define GPIO_GPIO0_BASE (0x50000000) +#define GPIO_GPIO1_BASE (0x50010000) +#define GPIO_GPIO2_BASE (0x50020000) +#define GPIO_GPIO3_BASE (0x50030000) + +#define GPIO_GPIO0DATA (*(pREG32 (0x50003FFC))) // Port data register +#define GPIO_GPIO0DIR (*(pREG32 (0x50008000))) // Data direction register +#define GPIO_GPIO0IS (*(pREG32 (0x50008004))) // Interrupt sense register +#define GPIO_GPIO0IBE (*(pREG32 (0x50008008))) // Interrupt both edges register +#define GPIO_GPIO0IEV (*(pREG32 (0x5000800C))) // Interrupt event register +#define GPIO_GPIO0IE (*(pREG32 (0x50008010))) // Interrupt mask register +#define GPIO_GPIO0RIS (*(pREG32 (0x50008014))) // Raw interrupt status register +#define GPIO_GPIO0MIS (*(pREG32 (0x50008018))) // Masked interrupt status register +#define GPIO_GPIO0IC (*(pREG32 (0x5000801C))) // Interrupt clear register + +#define GPIO_GPIO1DATA (*(pREG32 (0x50013FFC))) // Port data register +#define GPIO_GPIO1DIR (*(pREG32 (0x50018000))) // Data direction register +#define GPIO_GPIO1IS (*(pREG32 (0x50018004))) // Interrupt sense register +#define GPIO_GPIO1IBE (*(pREG32 (0x50018008))) // Interrupt both edges register +#define GPIO_GPIO1IEV (*(pREG32 (0x5001800C))) // Interrupt event register +#define GPIO_GPIO1IE (*(pREG32 (0x50018010))) // Interrupt mask register +#define GPIO_GPIO1RIS (*(pREG32 (0x50018014))) // Raw interrupt status register +#define GPIO_GPIO1MIS (*(pREG32 (0x50018018))) // Masked interrupt status register +#define GPIO_GPIO1IC (*(pREG32 (0x5001801C))) // Interrupt clear register + +#define GPIO_GPIO2DATA (*(pREG32 (0x50023FFC))) // Port data register +#define GPIO_GPIO2DIR (*(pREG32 (0x50028000))) // Data direction register +#define GPIO_GPIO2IS (*(pREG32 (0x50028004))) // Interrupt sense register +#define GPIO_GPIO2IBE (*(pREG32 (0x50028008))) // Interrupt both edges register +#define GPIO_GPIO2IEV (*(pREG32 (0x5002800C))) // Interrupt event register +#define GPIO_GPIO2IE (*(pREG32 (0x50028010))) // Interrupt mask register +#define GPIO_GPIO2RIS (*(pREG32 (0x50028014))) // Raw interrupt status register +#define GPIO_GPIO2MIS (*(pREG32 (0x50028018))) // Masked interrupt status register +#define GPIO_GPIO2IC (*(pREG32 (0x5002801C))) // Interrupt clear register + +#define GPIO_GPIO3DATA (*(pREG32 (0x50033FFC))) // Port data register +#define GPIO_GPIO3DIR (*(pREG32 (0x50038000))) // Data direction register +#define GPIO_GPIO3IS (*(pREG32 (0x50038004))) // Interrupt sense register +#define GPIO_GPIO3IBE (*(pREG32 (0x50038008))) // Interrupt both edges register +#define GPIO_GPIO3IEV (*(pREG32 (0x5003800C))) // Interrupt event register +#define GPIO_GPIO3IE (*(pREG32 (0x50038010))) // Interrupt mask register +#define GPIO_GPIO3RIS (*(pREG32 (0x50038014))) // Raw interrupt status register +#define GPIO_GPIO3MIS (*(pREG32 (0x50038018))) // Masked interrupt status register +#define GPIO_GPIO3IC (*(pREG32 (0x5003801C))) // Interrupt clear register + +#define GPIO_IO_P0 ((unsigned int) 0x00000001) +#define GPIO_IO_P1 ((unsigned int) 0x00000002) +#define GPIO_IO_P2 ((unsigned int) 0x00000004) +#define GPIO_IO_P3 ((unsigned int) 0x00000008) +#define GPIO_IO_P4 ((unsigned int) 0x00000010) +#define GPIO_IO_P5 ((unsigned int) 0x00000020) +#define GPIO_IO_P6 ((unsigned int) 0x00000040) +#define GPIO_IO_P7 ((unsigned int) 0x00000080) +#define GPIO_IO_P8 ((unsigned int) 0x00000100) +#define GPIO_IO_P9 ((unsigned int) 0x00000200) +#define GPIO_IO_P10 ((unsigned int) 0x00000400) +#define GPIO_IO_P11 ((unsigned int) 0x00000800) +#define GPIO_IO_ALL ((unsigned int) 0x00000FFF) + +/*############################################################################## +## USB +##############################################################################*/ + +/* USB registers are defined in USB code */ +#define USB_BASE_ADDRESS (0x40020000) + +/* USB Device Interrupt Status Register */ +#define USB_DEVINTST (*(pREG32 (0x40020000))) +#define USB_DEVINTST_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTST_FRAME ((unsigned int) 0x00000001) // Frame interrupt +#define USB_DEVINTST_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTST_EP0 ((unsigned int) 0x00000002) // USB core interrupt for EP0 +#define USB_DEVINTST_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTST_EP1 ((unsigned int) 0x00000004) // USB core interrupt for EP1 +#define USB_DEVINTST_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTST_EP2 ((unsigned int) 0x00000008) // USB core interrupt for EP2 +#define USB_DEVINTST_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTST_EP3 ((unsigned int) 0x00000010) // USB core interrupt for EP3 +#define USB_DEVINTST_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTST_EP4 ((unsigned int) 0x00000020) // USB core interrupt for EP4 +#define USB_DEVINTST_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTST_EP5 ((unsigned int) 0x00000040) // USB core interrupt for EP5 +#define USB_DEVINTST_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTST_EP6 ((unsigned int) 0x00000080) // USB core interrupt for EP6 +#define USB_DEVINTST_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTST_EP7 ((unsigned int) 0x00000100) // USB core interrupt for EP7 +#define USB_DEVINTST_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTST_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTST_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTST_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTST_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTST_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTST_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTST_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTST_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTST_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Enable Register */ +#define USB_DEVINTEN (*(pREG32 (0x40020004))) +#define USB_DEVINTEN_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTEN_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTEN_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTEN_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTEN_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTEN_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTEN_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTEN_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTEN_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTEN_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTEN_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTEN_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTEN_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTEN_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTEN_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTEN_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTEN_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTEN_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTEN_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTEN_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTEN_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTEN_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTEN_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTEN_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTEN_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTEN_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTEN_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTEN_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Clear Register */ +#define USB_DEVINTCLR (*(pREG32 (0x40020008))) +#define USB_DEVINTCLR_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTCLR_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTCLR_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTCLR_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTCLR_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTCLR_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTCLR_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTCLR_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTCLR_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTCLR_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTCLR_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTCLR_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTCLR_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTCLR_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTCLR_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTCLR_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTCLR_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTCLR_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTCLR_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTCLR_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTCLR_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTCLR_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTCLR_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTCLR_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTCLR_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTCLR_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTCLR_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTCLR_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Device Interrupt Set Register */ +#define USB_DEVINTSET (*(pREG32 (0x4002000C))) +#define USB_DEVINTSET_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVINTSET_FRAME ((unsigned int) 0x00000001) +#define USB_DEVINTSET_EP0_MASK ((unsigned int) 0x00000002) +#define USB_DEVINTSET_EP0 ((unsigned int) 0x00000002) +#define USB_DEVINTSET_EP1_MASK ((unsigned int) 0x00000004) +#define USB_DEVINTSET_EP1 ((unsigned int) 0x00000004) +#define USB_DEVINTSET_EP2_MASK ((unsigned int) 0x00000008) +#define USB_DEVINTSET_EP2 ((unsigned int) 0x00000008) +#define USB_DEVINTSET_EP3_MASK ((unsigned int) 0x00000010) +#define USB_DEVINTSET_EP3 ((unsigned int) 0x00000010) +#define USB_DEVINTSET_EP4_MASK ((unsigned int) 0x00000020) +#define USB_DEVINTSET_EP4 ((unsigned int) 0x00000020) +#define USB_DEVINTSET_EP5_MASK ((unsigned int) 0x00000040) +#define USB_DEVINTSET_EP5 ((unsigned int) 0x00000040) +#define USB_DEVINTSET_EP6_MASK ((unsigned int) 0x00000080) +#define USB_DEVINTSET_EP6 ((unsigned int) 0x00000080) +#define USB_DEVINTSET_EP7_MASK ((unsigned int) 0x00000100) +#define USB_DEVINTSET_EP7 ((unsigned int) 0x00000100) +#define USB_DEVINTSET_DEV_START_MASK ((unsigned int) 0x00000200) +#define USB_DEVINTSET_DEV_START ((unsigned int) 0x00000200) +#define USB_DEVINTSET_CC_EMPTY_MASK ((unsigned int) 0x00000400) +#define USB_DEVINTSET_CC_EMPTY ((unsigned int) 0x00000400) +#define USB_DEVINTSET_CD_FULL_MASK ((unsigned int) 0x00000800) +#define USB_DEVINTSET_CD_FULL ((unsigned int) 0x00000800) +#define USB_DEVINTSET_RxENDPKT_MASK ((unsigned int) 0x00001000) +#define USB_DEVINTSET_RxENDPKT ((unsigned int) 0x00001000) +#define USB_DEVINTSET_TxENDPKT_MASK ((unsigned int) 0x00002000) +#define USB_DEVINTSET_TxENDPKT ((unsigned int) 0x00002000) + +/* USB Command Code Register */ +#define USB_CMDCODE (*(pREG32 (0x40020010))) +#define USB_CMDCODE_CMD_PHASE_WRITE ((unsigned int) 0x00000100) +#define USB_CMDCODE_CMD_PHASE_READ ((unsigned int) 0x00000200) +#define USB_CMDCODE_CMD_PHASE_COMMAND ((unsigned int) 0x00000500) +#define USB_CMDCODE_CMD_PHASE_MASK ((unsigned int) 0x0000FF00) +#define USB_CMDCODE_CMD_CODE_MASK ((unsigned int) 0x00FF0000) +#define USB_CMDCODE_CMD_WDATA_MASK ((unsigned int) 0x00FF0000) + +/* USB Command Data Register */ +#define USB_CMDDATA (*(pREG32 (0x40020014))) +#define USB_CMDDATA_CMD_RDATA_MASK ((unsigned int) 0x000000FF) + +/* USB Receive Data Register */ +#define USB_RXDATA (*(pREG32 (0x40020018))) + +/* USB Transmit Data Register */ +#define USB_TXDATA (*(pREG32 (0x4002001C))) + +/* USB Receive Packet Length Register */ +#define USB_RXPLEN (*(pREG32 (0x40020020))) +#define USB_RXPLEN_PKT_LNGTH_MASK ((unsigned int) 0x000003FF) +#define USB_RXPLEN_DV_MASK ((unsigned int) 0x00000400) +#define USB_RXPLEN_DV ((unsigned int) 0x00000400) + +/* USB Transmit Packet Length Register */ +#define USB_TXPLEN (*(pREG32 (0x40020024))) +#define USB_TXPLEN_PKT_LNGTH_MASK 0x3FF + +/* USB Control Register */ +#define USB_CTRL (*(pREG32 (0x40020028))) +#define USB_CTRL_RD_EN_MASK ((unsigned int) 0x00000001) +#define USB_CTRL_RD_EN ((unsigned int) 0x00000001) +#define USB_CTRL_WR_EN_MASK ((unsigned int) 0x00000002) +#define USB_CTRL_WR_EN ((unsigned int) 0x00000002) +#define USB_CTRL_LOG_ENDPOINT_MASK ((unsigned int) 0x0000003C) + +/* USB Device FIQ Select Register */ +#define USB_DEVFIQSEL (*(pREG32 (0x4002002C))) +#define USB_DEVFIQSEL_FRAME_MASK ((unsigned int) 0x00000001) +#define USB_DEVFIQSEL_FRAME ((unsigned int) 0x00000001) +#define USB_DEVFIQSEL_BULKOUT_MASK ((unsigned int) 0x00000002) +#define USB_DEVFIQSEL_BULKOUT ((unsigned int) 0x00000002) +#define USB_DEVFIQSEL_BULKIN_MASK ((unsigned int) 0x00000004) +#define USB_DEVFIQSEL_BULKIN ((unsigned int) 0x00000004) + +/*############################################################################## +## UART +##############################################################################*/ + +#define UART_BASE_ADDRESS (0x40008000) + +#define UART_U0RBR (*(pREG32 (0x40008000))) // Receive buffer +#define UART_U0THR (*(pREG32 (0x40008000))) // Transmitter holding register +#define UART_U0DLL (*(pREG32 (0x40008000))) // Divisor latch LSB +#define UART_U0DLM (*(pREG32 (0x40008004))) // Divisor latch MSB +#define UART_U0IER (*(pREG32 (0x40008004))) // Interrupt enable +#define UART_U0IIR (*(pREG32 (0x40008008))) // Interrupt identification +#define UART_U0FCR (*(pREG32 (0x40008008))) // FIFO control +#define UART_U0MCR (*(pREG32 (0x40008010))) // Modem control +#define UART_U0LCR (*(pREG32 (0x4000800C))) // Line control +#define UART_U0LSR (*(pREG32 (0x40008014))) // Line status +#define UART_U0MSR (*(pREG32 (0x40008018))) // Modem status +#define UART_U0SCR (*(pREG32 (0x4000801C))) // Scratch pad +#define UART_U0ACR (*(pREG32 (0x40008020))) // Auto-baud control +#define UART_U0FDR (*(pREG32 (0x40008028))) // Fractional divider +#define UART_U0TER (*(pREG32 (0x40008030))) // Transmit enable +#define UART_U0RS485CTRL (*(pREG32 (0x4000804C))) // RS485 control register +#define UART_U0RS485ADRMATCH (*(pREG32 (0x40008050))) // RS485 address match +#define UART_U0RS485DLY (*(pREG32 (0x40008054))) // RS485 Delay value +#define UART_U0FIFOLVL (*(pREG32 (0x40008058))) // UART FIFO level + +#define UART_U0RBR_MASK ((unsigned int) 0x000000FF) + +#define UART_U0IER_RBR_Interrupt_MASK ((unsigned int) 0x00000001) // Enables the received data available interrupt +#define UART_U0IER_RBR_Interrupt_Enabled ((unsigned int) 0x00000001) +#define UART_U0IER_RBR_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_THRE_Interrupt_MASK ((unsigned int) 0x00000002) // Enables the THRE interrupt +#define UART_U0IER_THRE_Interrupt_Enabled ((unsigned int) 0x00000002) +#define UART_U0IER_THRE_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_RLS_Interrupt_MASK ((unsigned int) 0x00000004) // Enables the Rx line status interrupt +#define UART_U0IER_RLS_Interrupt_Enabled ((unsigned int) 0x00000004) +#define UART_U0IER_RLS_Interrupt_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_ABEOIntEn_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt +#define UART_U0IER_ABEOIntEn_Enabled ((unsigned int) 0x00000100) +#define UART_U0IER_ABEOIntEn_Disabled ((unsigned int) 0x00000000) +#define UART_U0IER_ABTOIntEn_MASK ((unsigned int) 0x00000200) // Auto-baud timeout interrupt +#define UART_U0IER_ABTOIntEn_Enabled ((unsigned int) 0x00000200) +#define UART_U0IER_ABTOIntEn_Disabled ((unsigned int) 0x00000000) + +#define UART_U0IIR_IntStatus_MASK ((unsigned int) 0x00000001) // Interrupt status +#define UART_U0IIR_IntStatus_InterruptPending ((unsigned int) 0x00000001) +#define UART_U0IIR_IntStatus_NoInterruptPending ((unsigned int) 0x00000000) +#define UART_U0IIR_IntId_MASK ((unsigned int) 0x0000000E) // Interrupt identification +#define UART_U0IIR_IntId_RLS ((unsigned int) 0x00000006) // Receive line status +#define UART_U0IIR_IntId_RDA ((unsigned int) 0x00000004) // Receive data available +#define UART_U0IIR_IntId_CTI ((unsigned int) 0x0000000C) // Character time-out indicator +#define UART_U0IIR_IntId_THRE ((unsigned int) 0x00000002) // THRE interrupt +#define UART_U0IIR_IntId_MODEM ((unsigned int) 0x00000000) // Modem interrupt +#define UART_U0IIR_FIFO_Enable_MASK ((unsigned int) 0x000000C0) +#define UART_U0IIR_ABEOInt_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt +#define UART_U0IIR_ABEOInt ((unsigned int) 0x00000100) +#define UART_U0IIR_ABTOInt_MASK ((unsigned int) 0x00000200) // Auto-baud time-out interrupt +#define UART_U0IIR_ABTOInt ((unsigned int) 0x00000200) + +#define UART_U0FCR_FIFO_Enable_MASK ((unsigned int) 0x00000001) // UART FIFOs enabled/disabled +#define UART_U0FCR_FIFO_Enabled ((unsigned int) 0x00000001) +#define UART_U0FCR_FIFO_Disabled ((unsigned int) 0x00000000) +#define UART_U0FCR_Rx_FIFO_Reset_MASK ((unsigned int) 0x00000002) +#define UART_U0FCR_Rx_FIFO_Reset ((unsigned int) 0x00000002) // Clear Rx FIFO +#define UART_U0FCR_Tx_FIFO_Reset_MASK ((unsigned int) 0x00000004) +#define UART_U0FCR_Tx_FIFO_Reset ((unsigned int) 0x00000004) // Clear Tx FIFO +#define UART_U0FCR_Rx_Trigger_Level_Select_MASK ((unsigned int) 0x000000C0) // Chars written before before interrupt +#define UART_U0FCR_Rx_Trigger_Level_Select_1Char ((unsigned int) 0x00000000) +#define UART_U0FCR_Rx_Trigger_Level_Select_4Char ((unsigned int) 0x00000040) +#define UART_U0FCR_Rx_Trigger_Level_Select_8Char ((unsigned int) 0x00000080) +#define UART_U0FCR_Rx_Trigger_Level_Select_12Char ((unsigned int) 0x000000C0) + +#define UART_U0MCR_DTR_Control_MASK ((unsigned int) 0x00000001) // Source for modem output pin DTR +#define UART_U0MCR_DTR_Control ((unsigned int) 0x00000001) +#define UART_U0MCR_RTS_Control_MASK ((unsigned int) 0x00000002) // Source for modem output pin RTS +#define UART_U0MCR_RTS_Control ((unsigned int) 0x00000002) +#define UART_U0MCR_Loopback_Mode_Select_MASK ((unsigned int) 0x00000010) // Diagnostic loopback mode +#define UART_U0MCR_Loopback_Mode_Select_Enabled ((unsigned int) 0x00000010) +#define UART_U0MCR_Loopback_Mode_Select_Disabled ((unsigned int) 0x00000000) +#define UART_U0MCR_RTSen_MASK ((unsigned int) 0x00000040) // Disable auto-rts flow control +#define UART_U0MCR_RTSen_Enabled ((unsigned int) 0x00000040) +#define UART_U0MCR_RTSen_Disabled ((unsigned int) 0x00000000) +#define UART_U0MCR_CTSen_MASK ((unsigned int) 0x00000080) // Disable auto-cts flow control +#define UART_U0MCR_CTSen_Enabled ((unsigned int) 0x00000080) +#define UART_U0MCR_CTSen_Disabled ((unsigned int) 0x00000000) + +#define UART_U0LCR_Word_Length_Select_MASK ((unsigned int) 0x00000003) // Word Length Selector +#define UART_U0LCR_Word_Length_Select_5Chars ((unsigned int) 0x00000000) +#define UART_U0LCR_Word_Length_Select_6Chars ((unsigned int) 0x00000001) +#define UART_U0LCR_Word_Length_Select_7Chars ((unsigned int) 0x00000002) +#define UART_U0LCR_Word_Length_Select_8Chars ((unsigned int) 0x00000003) +#define UART_U0LCR_Stop_Bit_Select_MASK ((unsigned int) 0x00000004) // Stop bit select +#define UART_U0LCR_Stop_Bit_Select_1Bits ((unsigned int) 0x00000000) +#define UART_U0LCR_Stop_Bit_Select_2Bits ((unsigned int) 0x00000004) +#define UART_U0LCR_Parity_Enable_MASK ((unsigned int) 0x00000008) // Parity enable +#define UART_U0LCR_Parity_Enabled ((unsigned int) 0x00000008) +#define UART_U0LCR_Parity_Disabled ((unsigned int) 0x00000000) +#define UART_U0LCR_Parity_Select_MASK ((unsigned int) 0x00000030) // Parity select +#define UART_U0LCR_Parity_Select_OddParity ((unsigned int) 0x00000000) +#define UART_U0LCR_Parity_Select_EvenParity ((unsigned int) 0x00000010) +#define UART_U0LCR_Parity_Select_Forced1 ((unsigned int) 0x00000020) +#define UART_U0LCR_Parity_Select_Forced0 ((unsigned int) 0x00000030) +#define UART_U0LCR_Break_Control_MASK ((unsigned int) 0x00000040) // Break transmission control +#define UART_U0LCR_Break_Control_Enabled ((unsigned int) 0x00000040) +#define UART_U0LCR_Break_Control_Disabled ((unsigned int) 0x00000000) +#define UART_U0LCR_Divisor_Latch_Access_MASK ((unsigned int) 0x00000080) // Divisor latch access +#define UART_U0LCR_Divisor_Latch_Access_Enabled ((unsigned int) 0x00000080) +#define UART_U0LCR_Divisor_Latch_Access_Disabled ((unsigned int) 0x00000000) + +#define UART_U0LSR_RDR_MASK ((unsigned int) 0x00000001) // Receiver data ready +#define UART_U0LSR_RDR_EMPTY ((unsigned int) 0x00000000) // U0RBR is empty +#define UART_U0LSR_RDR_DATA ((unsigned int) 0x00000001) // U0RBR contains valid data +#define UART_U0LSR_OE_MASK ((unsigned int) 0x00000002) // Overrun error +#define UART_U0LSR_OE ((unsigned int) 0x00000002) +#define UART_U0LSR_PE_MASK ((unsigned int) 0x00000004) // Parity error +#define UART_U0LSR_PE ((unsigned int) 0x00000004) +#define UART_U0LSR_FE_MASK ((unsigned int) 0x00000008) // Framing error +#define UART_U0LSR_FE ((unsigned int) 0x00000008) +#define UART_U0LSR_BI_MASK ((unsigned int) 0x00000010) // Break interrupt +#define UART_U0LSR_BI ((unsigned int) 0x00000010) +#define UART_U0LSR_THRE_MASK ((unsigned int) 0x00000020) // Transmitter holding register empty +#define UART_U0LSR_THRE ((unsigned int) 0x00000020) +#define UART_U0LSR_TEMT_MASK ((unsigned int) 0x00000040) // Transmitter empty +#define UART_U0LSR_TEMT ((unsigned int) 0x00000040) +#define UART_U0LSR_RXFE_MASK ((unsigned int) 0x00000080) // Error in Rx FIFO +#define UART_U0LSR_RXFE ((unsigned int) 0x00000080) + +#define UART_U0MSR_Delta_CTS_MASK ((unsigned int) 0x00000001) // State change of input CTS +#define UART_U0MSR_Delta_CTS ((unsigned int) 0x00000001) +#define UART_U0MSR_Delta_DSR_MASK ((unsigned int) 0x00000002) // State change of input DSR +#define UART_U0MSR_Delta_DSR ((unsigned int) 0x00000002) +#define UART_U0MSR_Trailing_Edge_RI_MASK ((unsigned int) 0x00000004) // Low to high transition of input RI +#define UART_U0MSR_Trailing_Edge_RI ((unsigned int) 0x00000004) +#define UART_U0MSR_Delta_DCD_MASK ((unsigned int) 0x00000008) // State change of input DCD +#define UART_U0MSR_Delta_DCD ((unsigned int) 0x00000008) +#define UART_U0MSR_CTS_MASK ((unsigned int) 0x00000010) // Clear to send state +#define UART_U0MSR_CTS ((unsigned int) 0x00000010) +#define UART_U0MSR_DSR_MASK ((unsigned int) 0x00000020) // Data set ready state +#define UART_U0MSR_DSR ((unsigned int) 0x00000020) +#define UART_U0MSR_RI_MASK ((unsigned int) 0x00000040) // Ring indicator state +#define UART_U0MSR_RI ((unsigned int) 0x00000040) +#define UART_U0MSR_DCD_MASK ((unsigned int) 0x00000080) // Data carrier detect state +#define UART_U0MSR_DCD ((unsigned int) 0x00000080) + +#define UART_U0ACR_Start_MASK ((unsigned int) 0x00000001) // Auto-baud start/stop +#define UART_U0ACR_Start ((unsigned int) 0x00000001) +#define UART_U0ACR_Stop ((unsigned int) 0x00000000) +#define UART_U0ACR_Mode_MASK ((unsigned int) 0x00000002) // Auto-baud mode select +#define UART_U0ACR_Mode_Mode1 ((unsigned int) 0x00000000) +#define UART_U0ACR_Mode_Mode2 ((unsigned int) 0x00000002) +#define UART_U0ACR_AutoRestart_MASK ((unsigned int) 0x00000004) +#define UART_U0ACR_AutoRestart_NoRestart ((unsigned int) 0x00000000) +#define UART_U0ACR_AutoRestart_Restart ((unsigned int) 0x00000004) // Restart in case of time-out +#define UART_U0ACR_ABEOIntClr_MASK ((unsigned int) 0x00000100) // End of auto-baud interrupt clear bit +#define UART_U0ACR_ABEOIntClr ((unsigned int) 0x00000100) +#define UART_U0ACR_ABTOIntClr_MASK ((unsigned int) 0x00000200) // Auto-baud timeout interrupt clear bit +#define UART_U0ACR_ABTOIntClr ((unsigned int) 0x00000200) + +#define UART_U0FDR_DIVADDVAL_MASK ((unsigned int) 0x0000000F) // Fractional divider: prescaler register +#define UART_U0FDR_MULVAL_MASK ((unsigned int) 0x000000F0) // Fractional divider: prescaler multiplier + +#define UART_U0TER_TXEN_MASK ((unsigned int) 0x00000080) // UART transmit enable +#define UART_U0TER_TXEN_Enabled ((unsigned int) 0x00000080) +#define UART_U0TER_TXEN_Disabled ((unsigned int) 0x00000000) + +#define UART_U0RS485CTRL_NMMEN_MASK ((unsigned int) 0x00000001) // Normal multi-drop mode +#define UART_U0RS485CTRL_NMMEN ((unsigned int) 0x00000001) +#define UART_U0RS485CTRL_RXDIS_MASK ((unsigned int) 0x00000002) // Receiver +#define UART_U0RS485CTRL_RXDIS ((unsigned int) 0x00000002) +#define UART_U0RS485CTRL_AADEN_MASK ((unsigned int) 0x00000004) // Auto-address detect +#define UART_U0RS485CTRL_AADEN ((unsigned int) 0x00000004) +#define UART_U0RS485CTRL_SEL_MASK ((unsigned int) 0x00000008) +#define UART_U0RS485CTRL_SEL_RTS ((unsigned int) 0x00000000) // Use RTS for direction control +#define UART_U0RS485CTRL_SEL_DTS ((unsigned int) 0x00000008) // Use DTS for direction control +#define UART_U0RS485CTRL_DCTRL_MASK ((unsigned int) 0x00000010) // Enable/Disable auto-direction control +#define UART_U0RS485CTRL_DCTRL_Disabled ((unsigned int) 0x00000000) +#define UART_U0RS485CTRL_DCTRL_Enabled ((unsigned int) 0x00000010) +#define UART_U0RS485CTRL_OINV_MASK ((unsigned int) 0x00000020) // Reverse polarity of direction control signal on RTS/DTR pin +#define UART_U0RS485CTRL_OINV_Normal ((unsigned int) 0x00000000) +#define UART_U0RS485CTRL_OINV_Inverted ((unsigned int) 0x00000020) + +#define UART_U0FIFOLVL_RXFIFOLVL_MASK ((unsigned int) 0x0000000F) +#define UART_U0FIFOLVL_RXFIFOLVL_Empty ((unsigned int) 0x00000000) +#define UART_U0FIFOLVL_RXFIFOLVL_Full ((unsigned int) 0x0000000F) +#define UART_U0FIFOLVL_TXFIFOLVL_MASK ((unsigned int) 0x00000F00) +#define UART_U0FIFOLVL_TXFIFOLVL_Empty ((unsigned int) 0x00000000) +#define UART_U0FIFOLVL_TXFIFOLVL_Full ((unsigned int) 0x00000F00) + +/*############################################################################## +## SSP - Synchronous Serial Port +##############################################################################*/ + +#define SSP_SSP0_BASE_ADDRESS (0x40040000) + +#define SSP_SSP0CR0 (*(pREG32 (0x40040000))) // Control register 0 +#define SSP_SSP0CR1 (*(pREG32 (0x40040004))) // Control register 1 +#define SSP_SSP0DR (*(pREG32 (0x40040008))) // Data register +#define SSP_SSP0SR (*(pREG32 (0x4004000C))) // Status register +#define SSP_SSP0CPSR (*(pREG32 (0x40040010))) // Clock prescale register +#define SSP_SSP0IMSC (*(pREG32 (0x40040014))) // Interrupt mask set/clear register +#define SSP_SSP0RIS (*(pREG32 (0x40040018))) // Raw interrupt status register +#define SSP_SSP0MIS (*(pREG32 (0x4004001C))) // Masked interrupt status register +#define SSP_SSP0ICR (*(pREG32 (0x40040020))) // SSPICR interrupt clear register + +/* SSP0CR0 (SSP0 Control Register 0) + This register controls the basic operation of the SSP controller. */ + +#define SSP_SSP0CR0_DSS_MASK ((unsigned int) 0x0000000F) // Data size select +#define SSP_SSP0CR0_DSS_4BIT ((unsigned int) 0x00000003) +#define SSP_SSP0CR0_DSS_5BIT ((unsigned int) 0x00000004) +#define SSP_SSP0CR0_DSS_6BIT ((unsigned int) 0x00000005) +#define SSP_SSP0CR0_DSS_7BIT ((unsigned int) 0x00000006) +#define SSP_SSP0CR0_DSS_8BIT ((unsigned int) 0x00000007) +#define SSP_SSP0CR0_DSS_9BIT ((unsigned int) 0x00000008) +#define SSP_SSP0CR0_DSS_10BIT ((unsigned int) 0x00000009) +#define SSP_SSP0CR0_DSS_11BIT ((unsigned int) 0x0000000A) +#define SSP_SSP0CR0_DSS_12BIT ((unsigned int) 0x0000000B) +#define SSP_SSP0CR0_DSS_13BIT ((unsigned int) 0x0000000C) +#define SSP_SSP0CR0_DSS_14BIT ((unsigned int) 0x0000000D) +#define SSP_SSP0CR0_DSS_15BIT ((unsigned int) 0x0000000E) +#define SSP_SSP0CR0_DSS_16BIT ((unsigned int) 0x0000000F) +#define SSP_SSP0CR0_FRF_MASK ((unsigned int) 0x00000030) // Frame format +#define SSP_SSP0CR0_FRF_SPI ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_FRF_TI ((unsigned int) 0x00000010) +#define SSP_SSP0CR0_FRF_MWIRE ((unsigned int) 0x00000020) +#define SSP_SSP0CR0_CPOL_MASK ((unsigned int) 0x00000040) // Clock out polarity +#define SSP_SSP0CR0_CPOL_LOW ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_CPOL_HIGH ((unsigned int) 0x00000040) +#define SSP_SSP0CR0_CPHA_MASK ((unsigned int) 0x00000080) // Clock out phase +#define SSP_SSP0CR0_CPHA_FIRST ((unsigned int) 0x00000000) +#define SSP_SSP0CR0_CPHA_SECOND ((unsigned int) 0x00000080) + +/* Serial Clock Rate. The number of prescaler-output clocks per + bit on the bus, minus one. Given that CPSDVSR is the + prescale divider, and the APB clock PCLK clocks the + prescaler, the bit frequency is PCLK / (CPSDVSR — [SCR+1]). */ + +#define SSP_SSP0CR0_SCR_MASK ((unsigned int) 0x0000FF00) // Serial clock rate +#define SSP_SSP0CR0_SCR_1 ((unsigned int) 0x00000100) +#define SSP_SSP0CR0_SCR_2 ((unsigned int) 0x00000200) +#define SSP_SSP0CR0_SCR_3 ((unsigned int) 0x00000300) +#define SSP_SSP0CR0_SCR_4 ((unsigned int) 0x00000400) +#define SSP_SSP0CR0_SCR_5 ((unsigned int) 0x00000500) +#define SSP_SSP0CR0_SCR_6 ((unsigned int) 0x00000600) +#define SSP_SSP0CR0_SCR_7 ((unsigned int) 0x00000700) +#define SSP_SSP0CR0_SCR_8 ((unsigned int) 0x00000800) +#define SSP_SSP0CR0_SCR_9 ((unsigned int) 0x00000900) +#define SSP_SSP0CR0_SCR_10 ((unsigned int) 0x00000A00) +#define SSP_SSP0CR0_SCR_11 ((unsigned int) 0x00000B00) +#define SSP_SSP0CR0_SCR_12 ((unsigned int) 0x00000C00) +#define SSP_SSP0CR0_SCR_13 ((unsigned int) 0x00000D00) +#define SSP_SSP0CR0_SCR_14 ((unsigned int) 0x00000E00) +#define SSP_SSP0CR0_SCR_15 ((unsigned int) 0x00000F00) +#define SSP_SSP0CR0_SCR_16 ((unsigned int) 0x00001000) + +/* SSP0CR1 (SSP0 Control Register 1) + This register controls certain aspects of the operation of the SSP controller. */ + +#define SSP_SSP0CR1_LBM_MASK ((unsigned int) 0x00000001) // Loop back mode +#define SSP_SSP0CR1_LBM_NORMAL ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_LBM_INVERTED ((unsigned int) 0x00000001) // MISO/MOSI are reversed +#define SSP_SSP0CR1_SSE_MASK ((unsigned int) 0x00000002) // SSP enable +#define SSP_SSP0CR1_SSE_DISABLED ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_SSE_ENABLED ((unsigned int) 0x00000002) +#define SSP_SSP0CR1_MS_MASK ((unsigned int) 0x00000004) // Master/Slave Mode +#define SSP_SSP0CR1_MS_MASTER ((unsigned int) 0x00000000) +#define SSP_SSP0CR1_MS_SLAVE ((unsigned int) 0x00000004) +#define SSP_SSP0CR1_SOD_MASK ((unsigned int) 0x00000008) // Slave output disable + +/* SSP0DR (SSP0 Data Register) + Software can write data to be transmitted to this register, and read data that has been + received. */ + +#define SSP_SSP0DR_MASK ((unsigned int) 0x0000FFFF) // Data + +/* SSP0SR (SSP0 Status Register) + This read-only register reflects the current status of the SSP controller. */ + +#define SSP_SSP0SR_TFE_MASK ((unsigned int) 0x00000001) // Transmit FIFO empty +#define SSP_SSP0SR_TFE_EMPTY ((unsigned int) 0x00000001) +#define SSP_SSP0SR_TFE_NOTEMPTY ((unsigned int) 0x00000000) +#define SSP_SSP0SR_TNF_MASK ((unsigned int) 0x00000002) // Transmit FIFO not full +#define SSP_SSP0SR_TNF_NOTFULL ((unsigned int) 0x00000002) +#define SSP_SSP0SR_TNF_FULL ((unsigned int) 0x00000000) +#define SSP_SSP0SR_RNE_MASK ((unsigned int) 0x00000004) // Receive FIFO not empty +#define SSP_SSP0SR_RNE_NOTEMPTY ((unsigned int) 0x00000004) +#define SSP_SSP0SR_RNE_EMPTY ((unsigned int) 0x00000000) +#define SSP_SSP0SR_RFF_MASK ((unsigned int) 0x00000008) // Receive FIFO full +#define SSP_SSP0SR_RFF_FULL ((unsigned int) 0x00000008) +#define SSP_SSP0SR_RFF_NOTFULL ((unsigned int) 0x00000000) +#define SSP_SSP0SR_BSY_MASK ((unsigned int) 0x00000010) // Busy Flag +#define SSP_SSP0SR_BSY_IDLE ((unsigned int) 0x00000000) +#define SSP_SSP0SR_BSY_BUSY ((unsigned int) 0x00000010) + +/* SSP0CPSR (SSP0 Clock Prescale Register) + This register controls the factor by which the Prescaler divides the SSP peripheral clock + SSP_PCLK to yield the prescaler clock that is, in turn, divided by the SCR factor in + SSP0CR0, to determine the bit clock. */ + +#define SSP_SSP0CPSR_CPSDVSR_MASK ((unsigned int) 0x000000FF) +#define SSP_SSP0CPSR_CPSDVSR_DIV2 ((unsigned int) 0x00000002) +#define SSP_SSP0CPSR_CPSDVSR_DIV4 ((unsigned int) 0x00000004) +#define SSP_SSP0CPSR_CPSDVSR_DIV10 ((unsigned int) 0x0000000A) +#define SSP_SSP0CPSR_CPSDVSR_DIV12 ((unsigned int) 0x0000000C) +#define SSP_SSP0CPSR_CPSDVSR_DIV16 ((unsigned int) 0x00000010) +#define SSP_SSP0CPSR_CPSDVSR_DIV20 ((unsigned int) 0x00000014) + +/* SSP0IMSC (SSP0 Interrupt Mask Set/Clear Register) + This register controls whether each of the four possible interrupt conditions in the SSP + controller are enabled. Note that ARM uses the word “masked” in the opposite sense from + classic computer terminology, in which “masked” meant “disabled”. ARM uses the word + “masked” to mean “enabled”. To avoid confusion we will not use the word “masked”. */ + +#define SSP_SSP0IMSC_RORIM_MASK ((unsigned int) 0x00000001) // Receive overrun interrupt +#define SSP_SSP0IMSC_RORIM_ENBL ((unsigned int) 0x00000001) +#define SSP_SSP0IMSC_RORIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_RTIM_MASK ((unsigned int) 0x00000002) // Receive timeout interrupt +#define SSP_SSP0IMSC_RTIM_ENBL ((unsigned int) 0x00000002) +#define SSP_SSP0IMSC_RTIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_RXIM_MASK ((unsigned int) 0x00000004) // Rx FIFO >= 1/2 full interrupt +#define SSP_SSP0IMSC_RXIM_ENBL ((unsigned int) 0x00000004) +#define SSP_SSP0IMSC_RXIM_DSBL ((unsigned int) 0x00000000) +#define SSP_SSP0IMSC_TXIM_MASK ((unsigned int) 0x00000008) // Tx FIFO >= 1/2 empty interrupt +#define SSP_SSP0IMSC_TXIM_ENBL ((unsigned int) 0x00000008) +#define SSP_SSP0IMSC_TXIM_DSBL ((unsigned int) 0x00000000) + +/* SSP0RIS (SSP0 Raw Interrupt Status Register) + This read-only register contains a 1 for each interrupt condition that is asserted, + regardless of whether or not the interrupt is enabled in the SSP0IMSC. */ + +#define SSP_SSP0RIS_RORRIS_MASK ((unsigned int) 0x00000001) // Frame received while Rx FIFO full +#define SSP_SSP0RIS_RORRIS_RCVD ((unsigned int) 0x00000001) +#define SSP_SSP0RIS_RTRIS_MASK ((unsigned int) 0x00000002) // Rx FIFO not empty no read within timeout +#define SSP_SSP0RIS_RTRIS_NOTEMPTY ((unsigned int) 0x00000002) +#define SSP_SSP0RIS_RXRIS_MASK ((unsigned int) 0x00000004) // Rx FIFO >= half full +#define SSP_SSP0RIS_RXRIS_HALFFULL ((unsigned int) 0x00000004) +#define SSP_SSP0RIS_TXRIS_MASK ((unsigned int) 0x00000008) // Tx FIF0 >= half-empty +#define SSP_SSP0RIS_TXRIS_HALFEMPTY ((unsigned int) 0x00000008) + +/* SSP0MIS (SSP0 Masked Interrupt Status Register) + This read-only register contains a 1 for each interrupt condition that is asserted and + enabled in the SSP0IMSC. When an SSP interrupt occurs, the interrupt service routine + should read this register to determine the cause(s) of the interrupt. */ + +#define SSP_SSP0MIS_RORMIS_MASK ((unsigned int) 0x00000001) // Frame received while Rx FIFO full +#define SSP_SSP0MIS_RORMIS_FRMRCVD ((unsigned int) 0x00000001) +#define SSP_SSP0MIS_RTMIS_MASK ((unsigned int) 0x00000002) // Rx FIFO not empty no read withing timeout +#define SSP_SSP0MIS_RTMIS_NOTEMPTY ((unsigned int) 0x00000002) +#define SSP_SSP0MIS_RXMIS_MASK ((unsigned int) 0x00000004) // Rx FIFO >= half full +#define SSP_SSP0MIS_RXMIS_HALFFULL ((unsigned int) 0x00000004) +#define SSP_SSP0MIS_TXMIS_MASK ((unsigned int) 0x00000008) // Tx FIFO >= half-empty +#define SSP_SSP0MIS_TXMIS_HALFEMPTY ((unsigned int) 0x00000008) + +/* SSP0ICR (SSP0 Interrupt Clear Register) + Software can write one or more one(s) to this write-only register, to clear the + corresponding interrupt condition(s) in the SSP controller. Note that the other two interrupt + conditions can be cleared by writing or reading the appropriate FIFO, or disabled by + clearing the corresponding bit in SSP0IMSC. */ + +#define SSP_SSP0ICR_RORIC_MASK ((unsigned int) 0x00000001) // Clears RORIC interrupt flag +#define SSP_SSP0ICR_RORIC_CLEAR ((unsigned int) 0x00000001) +#define SSP_SSP0ICR_RTIC_MASK ((unsigned int) 0x00000002) // Clear Rx FIFO not empty/no read flag +#define SSP_SSP0ICR_RTIC_CLEAR ((unsigned int) 0x00000002) + +/*############################################################################## +## I2C +##############################################################################*/ + +#define I2C_BASE_ADDRESS (0x40000000) + +#define I2C_I2CCONSET (*(pREG32 (0x40000000))) // I2C control set register +#define I2C_I2CSTAT (*(pREG32 (0x40000004))) // I2C status register +#define I2C_I2CDAT (*(pREG32 (0x40000008))) // I2C data register +#define I2C_I2CADR0 (*(pREG32 (0x4000000C))) // I2C slave address register +#define I2C_I2CSCLH (*(pREG32 (0x40000010))) // I2C SCL HIGH/LOW duty cycle register +#define I2C_I2CSCLL (*(pREG32 (0x40000014))) +#define I2C_I2CCONCLR (*(pREG32 (0x40000018))) // I2C control clear register +#define I2C_I2CMMCTRL (*(pREG32 (0x4000001C))) // I2C monitor control register +#define I2C_I2CADR1 (*(pREG32 (0x40000020))) // I2C slave address register 1 +#define I2C_I2CADR2 (*(pREG32 (0x40000024))) // I2C slave address register 2 +#define I2C_I2CADR3 (*(pREG32 (0x40000028))) // I2C slave address register 3 +#define I2C_I2CDATA_BUFFER (*(pREG32 (0x4000002C))) // I2C data buffer register +#define I2C_I2CMASK0 (*(pREG32 (0x40000030))) // I2C mask register 0 +#define I2C_I2CMASK1 (*(pREG32 (0x40000034))) // I2C mask register 1 +#define I2C_I2CMASK2 (*(pREG32 (0x40000038))) // I2C mask register 2 +#define I2C_I2CMASK3 (*(pREG32 (0x4000003C))) // I2C mask register 3 + +/* I2CCONSET (I2C Control Set register) + The I2CONSET registers control setting of bits in the I2CON register that controls + operation of the I2C interface. Writing a one to a bit of this register causes the + corresponding bit in the I2C control register to be set. Writing a zero has no effect. */ + +#define I2C_I2CCONSET_AA_MASK ((unsigned int) 0x00000004) +#define I2C_I2CCONSET_AA ((unsigned int) 0x00000004) // Asset acknowlegde flag +#define I2C_I2CCONSET_SI_MASK ((unsigned int) 0x00000008) +#define I2C_I2CCONSET_SI ((unsigned int) 0x00000008) // I2C interrupt flag +#define I2C_I2CCONSET_STO_MASK ((unsigned int) 0x00000010) +#define I2C_I2CCONSET_STO ((unsigned int) 0x00000010) // Stop flag +#define I2C_I2CCONSET_STA_MASK ((unsigned int) 0x00000020) +#define I2C_I2CCONSET_STA ((unsigned int) 0x00000020) // Start flag +#define I2C_I2CCONSET_I2EN_MASK ((unsigned int) 0x00000040) +#define I2C_I2CCONSET_I2EN ((unsigned int) 0x00000040) // I2C interface enable + +/* I2CSTAT (I2C Status register) + Each I2C Status register reflects the condition of the corresponding I2C interface. The I2C + Status register is Read-Only. */ + +#define I2C_I2CSTAT_Status_MASK ((unsigned int) 0x000000F8) // Status information + +/* I2CADR0 (I2C Slave Address register) + These registers are readable and writable and are only used when an I2C interface is set + to slave mode. */ + +#define I2C_I2CADR0_GC_MASK ((unsigned int) 0x00000001) +#define I2C_I2CADR0_GC ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR0_Address_MASK ((unsigned int) 0x000000FE) // I2C device address for slave mode + +/* I2CCONCLR (I2C Control Clear register) + The I2CONCLR registers control clearing of bits in the I2CON register that controls + operation of the I2C interface. Writing a one to a bit of this register causes the + corresponding bit in the I2C control register to be cleared. Writing a zero has no effect. */ + +#define I2C_I2CCONCLR_AAC_MASK ((unsigned int) 0x00000004) // Assert acknowledge clear bit +#define I2C_I2CCONCLR_AAC ((unsigned int) 0x00000004) +#define I2C_I2CCONCLR_SIC_MASK ((unsigned int) 0x00000008) // I2C interrupt clear bit +#define I2C_I2CCONCLR_SIC ((unsigned int) 0x00000008) +#define I2C_I2CCONCLR_STAC_MASK ((unsigned int) 0x00000020) // Start flag clear bit +#define I2C_I2CCONCLR_STAC ((unsigned int) 0x00000020) +#define I2C_I2CCONCLR_I2ENC_MASK ((unsigned int) 0x00000040) // I2C interface disable bit +#define I2C_I2CCONCLR_I2ENC ((unsigned int) 0x00000040) + +/* I2CMMCTRL (I2C Monitor mode control register) + This register controls the Monitor mode which allows the I2C module to monitor traffic on + the I2C bus without actually participating in traffic or interfering with the I2C bus. */ + +#define I2C_I2CMMCTRL_MM_ENA_MASK ((unsigned int) 0x00000001) // Monitor mode enable +#define I2C_I2CMMCTRL_MM_ENA_ENABLED ((unsigned int) 0x00000001) +#define I2C_I2CMMCTRL_MM_ENA_DISABLED ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_ENA_SCL_MASK ((unsigned int) 0x00000002) // SCL output enable +#define I2C_I2CMMCTRL_ENA_SCL_HOLDLOW ((unsigned int) 0x00000002) +#define I2C_I2CMMCTRL_ENA_SCL_FORCEHIGH ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_MATCH_ALL_MASK ((unsigned int) 0x00000008) // Select interrupt register match +#define I2C_I2CMMCTRL_MATCH_ALL_NORMAL ((unsigned int) 0x00000000) +#define I2C_I2CMMCTRL_MATCH_ALL_ANYADDRESS ((unsigned int) 0x00000008) + +/* I2CADR1..3 (I2C Slave Address registers) + These registers are readable and writable and are only used when an I2C interface is set + to slave mode. In master mode, this register has no effect. The LSB of I2ADR is the + General Call bit. When this bit is set, the General Call address (0x00) is recognized. */ + +#define I2C_I2CADR1_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR1_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR1_Address_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CADR2_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR2_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR2_Address_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CADR3_GC_MASK ((unsigned int) 0x00000001) // General call enable bit +#define I2C_I2CADR3_GC ((unsigned int) 0x00000001) +#define I2C_I2CADR3_Address_MASK ((unsigned int) 0x000000FE) + +/* I2CMASK0..3 (I2C Mask registers) */ + +#define I2C_I2CMASK0_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK1_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK2_MASK_MASK ((unsigned int) 0x000000FE) + +#define I2C_I2CMASK3_MASK_MASK ((unsigned int) 0x000000FE) + +/*############################################################################## +## 16-Bit Timers (CT16B0/1) +##############################################################################*/ + +#define TMR_CT16B0_BASE_ADDRESS (0x4000C000) + +#define TMR_TMR16B0IR (*(pREG32 (0x4000C000))) // Interrupt register +#define TMR_TMR16B0TCR (*(pREG32 (0x4000C004))) // Timer control register +#define TMR_TMR16B0TC (*(pREG32 (0x4000C008))) // Timer counter +#define TMR_TMR16B0PR (*(pREG32 (0x4000C00C))) // Prescale register +#define TMR_TMR16B0PC (*(pREG32 (0x4000C010))) // Prescale counter register +#define TMR_TMR16B0MCR (*(pREG32 (0x4000C014))) // Match control register +#define TMR_TMR16B0MR0 (*(pREG32 (0x4000C018))) // Match register 0 +#define TMR_TMR16B0MR1 (*(pREG32 (0x4000C01C))) // Match register 1 +#define TMR_TMR16B0MR2 (*(pREG32 (0x4000C020))) // Match register 2 +#define TMR_TMR16B0MR3 (*(pREG32 (0x4000C024))) // Match register 3 +#define TMR_TMR16B0CCR (*(pREG32 (0x4000C028))) // Capture control register +#define TMR_TMR16B0CR0 (*(pREG32 (0x4000C02C))) // Capture register +#define TMR_TMR16B0EMR (*(pREG32 (0x4000C03C))) // External match register +#define TMR_TMR16B0CTCR (*(pREG32 (0x4000C070))) // Count control register +#define TMR_TMR16B0PWMC (*(pREG32 (0x4000C074))) // PWM control register + +#define TMR_TMR16B0IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR16B0IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR16B0IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR16B0IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR16B0IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR16B0IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR16B0IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR16B0IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR16B0IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR16B0IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR16B0IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR16B0TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR16B0TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B0TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR16B0MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR16B0MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR16B0MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR16B0MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B0MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR16B0MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B0MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR16B0MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR16B0MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR16B0MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR16B0MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR16B0MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR16B0MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR16B0MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR16B0MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR16B0MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR16B0MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR16B0MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR16B0MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR16B0MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR16B0MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR16B0MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR16B0MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B0CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR16B0CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B0CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR16B0CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B0CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR16B0CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B0CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B0EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR16B0EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR16B0EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR16B0EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR16B0EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR16B0EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR16B0EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR16B0EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR16B0EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR16B0EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR16B0EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR16B0EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR16B0EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR16B0EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR16B0EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR16B0EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR16B0EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR16B0EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR16B0EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR16B0EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR16B0EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR16B0EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B0EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR16B0EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR16B0EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR16B0CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR16B0CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR16B0CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR16B0CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR16B0CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR16B0CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR16B0CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR16B0PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR16B0PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT16Bn_MAT0 +#define TMR_TMR16B0PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B0PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT16Bn_MAT1 +#define TMR_TMR16B0PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR16B0PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT16Bn_MAT2 +#define TMR_TMR16B0PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B0PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR16B0PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B0PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +#define TMR_CT16B1_BASE_ADDRESS (0x40010000) + +#define TMR_TMR16B1IR (*(pREG32 (0x40010000))) // Interrupt register +#define TMR_TMR16B1TCR (*(pREG32 (0x40010004))) // Timer control register +#define TMR_TMR16B1TC (*(pREG32 (0x40010008))) // Timer counter +#define TMR_TMR16B1PR (*(pREG32 (0x4001000C))) // Prescale register +#define TMR_TMR16B1PC (*(pREG32 (0x40010010))) // Prescale counter register +#define TMR_TMR16B1MCR (*(pREG32 (0x40010014))) // Match control register +#define TMR_TMR16B1MR0 (*(pREG32 (0x40010018))) // Match register 0 +#define TMR_TMR16B1MR1 (*(pREG32 (0x4001001C))) // Match register 1 +#define TMR_TMR16B1MR2 (*(pREG32 (0x40010020))) // Match register 2 +#define TMR_TMR16B1MR3 (*(pREG32 (0x40010024))) // Match register 3 +#define TMR_TMR16B1CCR (*(pREG32 (0x40010028))) // Capture control register +#define TMR_TMR16B1CR0 (*(pREG32 (0x4001002C))) // Capture register +#define TMR_TMR16B1EMR (*(pREG32 (0x4001003C))) // External match register +#define TMR_TMR16B1CTCR (*(pREG32 (0x40010070))) // Count control register +#define TMR_TMR16B1PWMC (*(pREG32 (0x40010074))) // PWM control register + +#define TMR_TMR16B1IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR16B1IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR16B1IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR16B1IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR16B1IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR16B1IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR16B1IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR16B1IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR16B1IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR16B1IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR16B1IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR16B1TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR16B1TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B1TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR16B1MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR16B1MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR16B1MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR16B1MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B1MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR16B1MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B1MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR16B1MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR16B1MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR16B1MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR16B1MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR16B1MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR16B1MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR16B1MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR16B1MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR16B1MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR16B1MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR16B1MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR16B1MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR16B1MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR16B1MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR16B1MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR16B1MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B1CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR16B1CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR16B1CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR16B1CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR16B1CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR16B1CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR16B1CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR16B1EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR16B1EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR16B1EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR16B1EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR16B1EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR16B1EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR16B1EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR16B1EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR16B1EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR16B1EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR16B1EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR16B1EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR16B1EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR16B1EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR16B1EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR16B1EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR16B1EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR16B1EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR16B1EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR16B1EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR16B1EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR16B1EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR16B1EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR16B1EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR16B1EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR16B1CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR16B1CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR16B1CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR16B1CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR16B1CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR16B1CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR16B1CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR16B1PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR16B1PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT16Bn_MAT0 +#define TMR_TMR16B1PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR16B1PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT16Bn_MAT1 +#define TMR_TMR16B1PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR16B1PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT16Bn_MAT2 +#define TMR_TMR16B1PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR16B1PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR16B1PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR16B1PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +/*############################################################################## +## 32-Bit Timers (CT32B0/1) +##############################################################################*/ + +#define TMR_CT32B0_BASE_ADDRESS (0x40014000) + +#define TMR_TMR32B0IR (*(pREG32 (0x40014000))) // Interrupt register +#define TMR_TMR32B0TCR (*(pREG32 (0x40014004))) // Timer control register +#define TMR_TMR32B0TC (*(pREG32 (0x40014008))) // Timer counter +#define TMR_TMR32B0PR (*(pREG32 (0x4001400C))) // Prescale register +#define TMR_TMR32B0PC (*(pREG32 (0x40014010))) // Prescale counter register +#define TMR_TMR32B0MCR (*(pREG32 (0x40014014))) // Match control register +#define TMR_TMR32B0MR0 (*(pREG32 (0x40014018))) // Match register 0 +#define TMR_TMR32B0MR1 (*(pREG32 (0x4001401C))) // Match register 1 +#define TMR_TMR32B0MR2 (*(pREG32 (0x40014020))) // Match register 2 +#define TMR_TMR32B0MR3 (*(pREG32 (0x40014024))) // Match register 3 +#define TMR_TMR32B0CCR (*(pREG32 (0x40014028))) // Capture control register +#define TMR_TMR32B0CR0 (*(pREG32 (0x4001402C))) // Capture register +#define TMR_TMR32B0EMR (*(pREG32 (0x4001403C))) // External match register +#define TMR_TMR32B0CTCR (*(pREG32 (0x40014070))) // Count control register +#define TMR_TMR32B0PWMC (*(pREG32 (0x40014074))) // PWM control register + +#define TMR_TMR32B0IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR32B0IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR32B0IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR32B0IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR32B0IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR32B0IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR32B0IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR32B0IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR32B0IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR32B0IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR32B0IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR32B0TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR32B0TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B0TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR32B0MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR32B0MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR32B0MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR32B0MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B0MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR32B0MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR32B0MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR32B0MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR32B0MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR32B0MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR32B0MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR32B0MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR32B0MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR32B0MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR32B0MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR32B0MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR32B0MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR32B0MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR32B0MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR32B0MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR32B0MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR32B0MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR32B0MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B0CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR32B0CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B0CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR32B0CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B0CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR32B0CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B0CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B0EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR32B0EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR32B0EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR32B0EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR32B0EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR32B0EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR32B0EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR32B0EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR32B0EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR32B0EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR32B0EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR32B0EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR32B0EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR32B0EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR32B0EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR32B0EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR32B0EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR32B0EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR32B0EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR32B0EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR32B0EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR32B0EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B0EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR32B0EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR32B0EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR32B0CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR32B0CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR32B0CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR32B0CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR32B0CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR32B0CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR32B0CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR32B0PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR32B0PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT32Bn_MAT0 +#define TMR_TMR32B0PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B0PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT32Bn_MAT1 +#define TMR_TMR32B0PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR32B0PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT32Bn_MAT2 +#define TMR_TMR32B0PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B0PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR32B0PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) // PWM mode is enabled for CT32Bn_MAT3 +#define TMR_TMR32B0PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +#define TMR_CT32B1_BASE_ADDRESS (0x40018000) + +#define TMR_TMR32B1IR (*(pREG32 (0x40018000))) // Interrupt register +#define TMR_TMR32B1TCR (*(pREG32 (0x40018004))) // Timer control register +#define TMR_TMR32B1TC (*(pREG32 (0x40018008))) // Timer counter +#define TMR_TMR32B1PR (*(pREG32 (0x4001800C))) // Prescale register +#define TMR_TMR32B1PC (*(pREG32 (0x40018010))) // Prescale counter register +#define TMR_TMR32B1MCR (*(pREG32 (0x40018014))) // Match control register +#define TMR_TMR32B1MR0 (*(pREG32 (0x40018018))) // Match register 0 +#define TMR_TMR32B1MR1 (*(pREG32 (0x4001801C))) // Match register 1 +#define TMR_TMR32B1MR2 (*(pREG32 (0x40018020))) // Match register 2 +#define TMR_TMR32B1MR3 (*(pREG32 (0x40018024))) // Match register 3 +#define TMR_TMR32B1CCR (*(pREG32 (0x40018028))) // Capture control register +#define TMR_TMR32B1CR0 (*(pREG32 (0x4001802C))) // Capture register +#define TMR_TMR32B1EMR (*(pREG32 (0x4001803C))) // External match register +#define TMR_TMR32B1CTCR (*(pREG32 (0x40018070))) // Count control register +#define TMR_TMR32B1PWMC (*(pREG32 (0x40018074))) // PWM control register + +#define TMR_TMR32B1IR_MR0_MASK ((unsigned int) 0x00000001) // Interrupt flag for match channel 0 +#define TMR_TMR32B1IR_MR0 ((unsigned int) 0x00000001) +#define TMR_TMR32B1IR_MR1_MASK ((unsigned int) 0x00000002) // Interrupt flag for match channel 1 +#define TMR_TMR32B1IR_MR1 ((unsigned int) 0x00000002) +#define TMR_TMR32B1IR_MR2_MASK ((unsigned int) 0x00000004) // Interrupt flag for match channel 2 +#define TMR_TMR32B1IR_MR2 ((unsigned int) 0x00000004) +#define TMR_TMR32B1IR_MR3_MASK ((unsigned int) 0x00000008) // Interrupt flag for match channel 3 +#define TMR_TMR32B1IR_MR3 ((unsigned int) 0x00000008) +#define TMR_TMR32B1IR_CR0_MASK ((unsigned int) 0x00000010) // Interrupt flag for capture channel 0 event +#define TMR_TMR32B1IR_CR0 ((unsigned int) 0x00000010) +#define TMR_TMR32B1IR_MASK_ALL ((unsigned int) 0x0000001F) + +#define TMR_TMR32B1TCR_COUNTERENABLE_MASK ((unsigned int) 0x00000001) // Counter enable +#define TMR_TMR32B1TCR_COUNTERENABLE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1TCR_COUNTERENABLE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1TCR_COUNTERRESET_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B1TCR_COUNTERRESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1TCR_COUNTERRESET_DISABLED ((unsigned int) 0x00000002) + +#define TMR_TMR32B1MCR_MR0_INT_MASK ((unsigned int) 0x00000001) // Interrupt on MRO +#define TMR_TMR32B1MCR_MR0_INT_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1MCR_MR0_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR0_RESET_MASK ((unsigned int) 0x00000002) // Reset on MR0 +#define TMR_TMR32B1MCR_MR0_RESET_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1MCR_MR0_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR0_STOP_MASK ((unsigned int) 0x00000004) // Stop on MR0 +#define TMR_TMR32B1MCR_MR0_STOP_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B1MCR_MR0_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_INT_MASK ((unsigned int) 0x00000008) // Interrupt on MR1 +#define TMR_TMR32B1MCR_MR1_INT_ENABLED ((unsigned int) 0x00000008) +#define TMR_TMR32B1MCR_MR1_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_RESET_MASK ((unsigned int) 0x00000010) // Reset on MR1 +#define TMR_TMR32B1MCR_MR1_RESET_ENABLED ((unsigned int) 0x00000010) +#define TMR_TMR32B1MCR_MR1_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR1_STOP_MASK ((unsigned int) 0x00000020) // Stop on MR1 +#define TMR_TMR32B1MCR_MR1_STOP_ENABLED ((unsigned int) 0x00000020) +#define TMR_TMR32B1MCR_MR1_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_INT_MASK ((unsigned int) 0x00000040) // Interrupt on MR2 +#define TMR_TMR32B1MCR_MR2_INT_ENABLED ((unsigned int) 0x00000040) +#define TMR_TMR32B1MCR_MR2_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_RESET_MASK ((unsigned int) 0x00000080) // Reset on MR2 +#define TMR_TMR32B1MCR_MR2_RESET_ENABLED ((unsigned int) 0x00000080) +#define TMR_TMR32B1MCR_MR2_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR2_STOP_MASK ((unsigned int) 0x00000100) // Stop on MR2 +#define TMR_TMR32B1MCR_MR2_STOP_ENABLED ((unsigned int) 0x00000100) +#define TMR_TMR32B1MCR_MR2_STOP_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_INT_MASK ((unsigned int) 0x00000200) // Interrupt on MR3 +#define TMR_TMR32B1MCR_MR3_INT_ENABLED ((unsigned int) 0x00000200) +#define TMR_TMR32B1MCR_MR3_INT_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_RESET_MASK ((unsigned int) 0x00000400) // Reset on MR3 +#define TMR_TMR32B1MCR_MR3_RESET_ENABLED ((unsigned int) 0x00000400) +#define TMR_TMR32B1MCR_MR3_RESET_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1MCR_MR3_STOP_MASK ((unsigned int) 0x00000800) // Stop on MR3 +#define TMR_TMR32B1MCR_MR3_STOP_ENABLED ((unsigned int) 0x00000800) +#define TMR_TMR32B1MCR_MR3_STOP_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B1CCR_CAP0RE_MASK ((unsigned int) 0x00000001) // Capture on rising edge +#define TMR_TMR32B1CCR_CAP0RE_ENABLED ((unsigned int) 0x00000001) +#define TMR_TMR32B1CCR_CAP0RE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1CCR_CAP0FE_MASK ((unsigned int) 0x00000002) // Capture on falling edge +#define TMR_TMR32B1CCR_CAP0FE_ENABLED ((unsigned int) 0x00000002) +#define TMR_TMR32B1CCR_CAP0FE_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1CCR_CAP0I_MASK ((unsigned int) 0x00000004) // Interrupt on CAP0 event +#define TMR_TMR32B1CCR_CAP0I_ENABLED ((unsigned int) 0x00000004) +#define TMR_TMR32B1CCR_CAP0I_DISABLED ((unsigned int) 0x00000000) + +#define TMR_TMR32B1EMR_EM0_MASK ((unsigned int) 0x00000001) // External match 0 +#define TMR_TMR32B1EMR_EM0 ((unsigned int) 0x00000001) +#define TMR_TMR32B1EMR_EMC0_MASK ((unsigned int) 0x00000030) +#define TMR_TMR32B1EMR_EMC0_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC0_LOW ((unsigned int) 0x00000010) +#define TMR_TMR32B1EMR_EMC0_HIGH ((unsigned int) 0x00000020) +#define TMR_TMR32B1EMR_EMC0_TOGGLE ((unsigned int) 0x00000030) +#define TMR_TMR32B1EMR_EM1_MASK ((unsigned int) 0x00000002) // External match 1 +#define TMR_TMR32B1EMR_EM1 ((unsigned int) 0x00000002) +#define TMR_TMR32B1EMR_EMC1_MASK ((unsigned int) 0x000000C0) +#define TMR_TMR32B1EMR_EMC1_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC1_LOW ((unsigned int) 0x00000040) +#define TMR_TMR32B1EMR_EMC1_HIGH ((unsigned int) 0x00000080) +#define TMR_TMR32B1EMR_EMC1_TOGGLE ((unsigned int) 0x000000C0) +#define TMR_TMR32B1EMR_EM2_MASK ((unsigned int) 0x00000004) // External match 2 +#define TMR_TMR32B1EMR_EM2 ((unsigned int) 0x00000004) +#define TMR_TMR32B1EMR_EMC2_MASK ((unsigned int) 0x00000300) +#define TMR_TMR32B1EMR_EMC2_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC2_LOW ((unsigned int) 0x00000100) +#define TMR_TMR32B1EMR_EMC2_HIGH ((unsigned int) 0x00000200) +#define TMR_TMR32B1EMR_EMC2_TOGGLE ((unsigned int) 0x00000300) +#define TMR_TMR32B1EMR_EM3_MASK ((unsigned int) 0x00000008) // External match 3 +#define TMR_TMR32B1EMR_EM3 ((unsigned int) 0x00000008) +#define TMR_TMR32B1EMR_EMC3_MASK ((unsigned int) 0x00000C00) +#define TMR_TMR32B1EMR_EMC3_DONOTHING ((unsigned int) 0x00000000) +#define TMR_TMR32B1EMR_EMC3_LOW ((unsigned int) 0x00000400) +#define TMR_TMR32B1EMR_EMC3_HIGH ((unsigned int) 0x00000800) +#define TMR_TMR32B1EMR_EMC3_TOGGLE ((unsigned int) 0x00000C00) + +#define TMR_TMR32B1CTCR_CTMODE_MASK ((unsigned int) 0x00000003) // Counter/Timer mode +#define TMR_TMR32B1CTCR_CTMODE_TIMER ((unsigned int) 0x00000000) // Timer Mode: Every rising PCLK edge +#define TMR_TMR32B1CTCR_CTMODE_COUNTERRISING ((unsigned int) 0x00000001) // Counter: TC increments on rising edge of input +#define TMR_TMR32B1CTCR_CTMODE_COUNTERFALLING ((unsigned int) 0x00000002) // Counter: TC increments on falling edge of input +#define TMR_TMR32B1CTCR_CTMODE_COUNTERBOTH ((unsigned int) 0x00000003) // Counter: TC increments on both edges of input +#define TMR_TMR32B1CTCR_CINPUTSELECT_MASK ((unsigned int) 0x0000000C) +#define TMR_TMR32B1CTCR_CINPUTSELECT ((unsigned int) 0x00000000) // CINPUTSELECT must be set to 00 + +#define TMR_TMR32B1PWMC_PWM0_MASK ((unsigned int) 0x00000001) +#define TMR_TMR32B1PWMC_PWM0_ENABLED ((unsigned int) 0x00000001) // PWM mode is enabled for CT32Bn_MAT0 +#define TMR_TMR32B1PWMC_PWM0_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM1_MASK ((unsigned int) 0x00000002) +#define TMR_TMR32B1PWMC_PWM1_ENABLED ((unsigned int) 0x00000002) // PWM mode is enabled for CT32Bn_MAT1 +#define TMR_TMR32B1PWMC_PWM1_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM2_MASK ((unsigned int) 0x00000004) +#define TMR_TMR32B1PWMC_PWM2_ENABLED ((unsigned int) 0x00000004) // PWM mode is enabled for CT32Bn_MAT2 +#define TMR_TMR32B1PWMC_PWM2_DISABLED ((unsigned int) 0x00000000) +#define TMR_TMR32B1PWMC_PWM3_MASK ((unsigned int) 0x00000008) +#define TMR_TMR32B1PWMC_PWM3_ENABLED ((unsigned int) 0x00000008) // PWM mode is enabled for CT32Bn_MAT3 +#define TMR_TMR32B1PWMC_PWM3_DISABLED ((unsigned int) 0x00000000) + +/*############################################################################## +## System Tick Timer +##############################################################################*/ + +#define SYSTICK_BASE_ADDRESS (0xE000E000) + +#define SYSTICK_STCTRL (*(pREG32 (0xE000E010))) // System tick control +#define SYSTICK_STRELOAD (*(pREG32 (0xE000E014))) // System timer reload +#define SYSTICK_STCURR (*(pREG32 (0xE000E018))) // System timer current +#define SYSTICK_STCALIB (*(pREG32 (0xE000E01C))) // System timer calibration + +/* STCTRL (System Timer Control and status register) + The STCTRL register contains control information for the System Tick Timer, and provides + a status flag. */ + +#define SYSTICK_STCTRL_ENABLE (0x00000001) // System tick counter enable +#define SYSTICK_STCTRL_TICKINT (0x00000002) // System tick interrupt enable +#define SYSTICK_STCTRL_CLKSOURCE (0x00000004) // NOTE: This isn't documented but is based on NXP examples +#define SYSTICK_STCTRL_COUNTFLAG (0x00010000) // System tick counter flag + +/* STRELOAD (System Timer Reload value register) + The STRELOAD register is set to the value that will be loaded into the System Tick Timer + whenever it counts down to zero. This register is loaded by software as part of timer + initialization. The STCALIB register may be read and used as the value for STRELOAD if + the CPU or external clock is running at the frequency intended for use with the STCALIB + value. */ + +#define SYSTICK_STRELOAD_MASK (0x00FFFFFF) + +/* STCURR (System Timer Current value register) + The STCURR register returns the current count from the System Tick counter when it is + read by software. */ + +#define SYSTICK_STCURR_MASK (0x00FFFFFF) + +/* STCALIB (System Timer Calibration value register) */ + +#define SYSTICK_STCALIB_TENMS_MASK (0x00FFFFFF) +#define SYSTICK_STCALIB_SKEW_MASK (0x40000000) +#define SYSTICK_STCALIB_NOREF_MASK (0x80000000) + +/*############################################################################## +## ADC +##############################################################################*/ + +#define ADC_AD0_BASE_ADDRESS (0x4001C000) + +#define ADC_AD0CR (*(pREG32 (0x4001C000))) // ADC Control Register +#define ADC_AD0GDR ((unsigned int) 0x4001C004) // ADC Global Data Register +#define ADC_AD0INTEN ((unsigned int) 0x4001C00C) // ADC Interrupt Enable Register +#define ADC_AD0DR0 ((unsigned int) 0x4001C010) // ADC Data Register 0 +#define ADC_AD0DR1 ((unsigned int) 0x4001C014) // ADC Data Register 1 +#define ADC_AD0DR2 ((unsigned int) 0x4001C018) // ADC Data Register 2 +#define ADC_AD0DR3 ((unsigned int) 0x4001C01C) // ADC Data Register 3 +#define ADC_AD0DR4 ((unsigned int) 0x4001C020) // ADC Data Register 4 +#define ADC_AD0DR5 ((unsigned int) 0x4001C024) // ADC Data Register 5 +#define ADC_AD0DR6 ((unsigned int) 0x4001C028) // ADC Data Register 6 +#define ADC_AD0DR7 ((unsigned int) 0x4001C02C) // ADC Data Register 7 +#define ADC_AD0STAT ((unsigned int) 0x4001C030) // ADC Status Register + +#define ADC_AD0CR_SEL_MASK (0x000000FF) +#define ADC_AD0CR_SEL_AD0 (0x00000001) +#define ADC_AD0CR_SEL_AD1 (0x00000002) +#define ADC_AD0CR_SEL_AD2 (0x00000004) +#define ADC_AD0CR_SEL_AD3 (0x00000008) +#define ADC_AD0CR_SEL_AD4 (0x00000010) +#define ADC_AD0CR_SEL_AD5 (0x00000020) +#define ADC_AD0CR_SEL_AD6 (0x00000040) +#define ADC_AD0CR_SEL_AD7 (0x00000080) +#define ADC_AD0CR_CLKDIV_MASK (0x0000FF00) +#define ADC_AD0CR_BURST_MASK (0x00010000) +#define ADC_AD0CR_BURST_SWMODE (0x00000000) +#define ADC_AD0CR_BURST_HWSCANMODE (0x00010000) +#define ADC_AD0CR_CLKS_MASK (0x000E0000) +#define ADC_AD0CR_CLKS_10BITS (0x00000000) +#define ADC_AD0CR_CLKS_9BITS (0x00020000) +#define ADC_AD0CR_CLKS_8BITS (0x00040000) +#define ADC_AD0CR_CLKS_7BITS (0x00060000) +#define ADC_AD0CR_CLKS_6BITS (0x00080000) +#define ADC_AD0CR_CLKS_5BITS (0x000A0000) +#define ADC_AD0CR_CLKS_4BITS (0x000C0000) +#define ADC_AD0CR_CLKS_3BITS (0x000E0000) +#define ADC_AD0CR_START_MASK (0x07000000) +#define ADC_AD0CR_START_NOSTART (0x00000000) +#define ADC_AD0CR_START_STARTNOW (0x01000000) +#define ADC_AD0CR_EDGE_MASK (0x08000000) +#define ADC_AD0CR_EDGE_FALLING (0x08000000) +#define ADC_AD0CR_EDGE_RISING (0x00000000) + +/* AD9GDR (A/D Global Data Register) + The A/D Global Data Register contains the result of the most recent A/D conversion. This + includes the data, DONE, and Overrun flags, and the number of the A/D channel to which + the data relates. */ + +#define ADC_AD0GDR_RESULT_MASK (0x0000FFC0) +#define ADC_AD0GDR_CHN_MASK (0x07000000) // Channel from which the results were converted +#define ADC_AD0GDR_OVERUN_MASK (0x40000000) +#define ADC_AD0GDR_OVERUN (0x40000000) +#define ADC_AD0GDR_DONE_MASK (0x80000000) +#define ADC_AD0GDR_DONE (0x80000000) + +/* AD0STAT (A/D Status Register) + The A/D Status register allows checking the status of all A/D channels simultaneously. + The DONE and OVERRUN flags appearing in the ADDRn register for each A/D channel + are mirrored in ADSTAT. The interrupt flag (the logical OR of all DONE flags) is also found + in ADSTAT. */ + +#define ADC_AD0STAT_DONE0_MASK (0x00000001) +#define ADC_AD0STAT_DONE0 (0x00000001) +#define ADC_AD0STAT_DONE1_MASK (0x00000002) +#define ADC_AD0STAT_DONE1 (0x00000002) +#define ADC_AD0STAT_DONE2_MASK (0x00000004) +#define ADC_AD0STAT_DONE2 (0x00000004) +#define ADC_AD0STAT_DONE3_MASK (0x00000008) +#define ADC_AD0STAT_DONE3 (0x00000008) +#define ADC_AD0STAT_DONE4_MASK (0x00000010) +#define ADC_AD0STAT_DONE4 (0x00000010) +#define ADC_AD0STAT_DONE5_MASK (0x00000020) +#define ADC_AD0STAT_DONE5 (0x00000020) +#define ADC_AD0STAT_DONE6_MASK (0x00000040) +#define ADC_AD0STAT_DONE6 (0x00000040) +#define ADC_AD0STAT_DONE7_MASK (0x00000080) +#define ADC_AD0STAT_DONE7 (0x00000080) +#define ADC_AD0STAT_OVERRUN0_MASK (0x00000100) +#define ADC_AD0STAT_OVERRUN0 (0x00000100) +#define ADC_AD0STAT_OVERRUN1_MASK (0x00000200) +#define ADC_AD0STAT_OVERRUN1 (0x00000200) +#define ADC_AD0STAT_OVERRUN2_MASK (0x00000400) +#define ADC_AD0STAT_OVERRUN2 (0x00000400) +#define ADC_AD0STAT_OVERRUN3_MASK (0x00000800) +#define ADC_AD0STAT_OVERRUN3 (0x00000800) +#define ADC_AD0STAT_OVERRUN4_MASK (0x00001000) +#define ADC_AD0STAT_OVERRUN4 (0x00001000) +#define ADC_AD0STAT_OVERRUN5_MASK (0x00002000) +#define ADC_AD0STAT_OVERRUN5 (0x00002000) +#define ADC_AD0STAT_OVERRUN6_MASK (0x00004000) +#define ADC_AD0STAT_OVERRUN6 (0x00004000) +#define ADC_AD0STAT_OVERRUN7_MASK (0x00008000) +#define ADC_AD0STAT_OVERRUN7 (0x00008000) +#define ADC_AD0STAT_ADINT_MASK (0x00010000) +#define ADC_AD0STAT_ADINT (0x00010000) + +/* ADINTEN0 (A/D Interrupt Enable Register) + This register allows control over which A/D channels generate an interrupt when a + conversion is complete. For example, it may be desirable to use some A/D channels to + monitor sensors by continuously performing conversions on them. The most recent + results are read by the application program whenever they are needed. In this case, an + interrupt is not desirable at the end of each conversion for some A/D channels. */ + +#define ADC_AD0INTEN_ADINTEN0_MASK (0x00000001) +#define ADC_AD0INTEN_ADINTEN0 (0x00000001) +#define ADC_AD0INTEN_ADINTEN1_MASK (0x00000002) +#define ADC_AD0INTEN_ADINTEN1 (0x00000002) +#define ADC_AD0INTEN_ADINTEN2_MASK (0x00000004) +#define ADC_AD0INTEN_ADINTEN2 (0x00000004) +#define ADC_AD0INTEN_ADINTEN3_MASK (0x00000008) +#define ADC_AD0INTEN_ADINTEN3 (0x00000008) +#define ADC_AD0INTEN_ADINTEN4_MASK (0x00000010) +#define ADC_AD0INTEN_ADINTEN4 (0x00000010) +#define ADC_AD0INTEN_ADINTEN5_MASK (0x00000020) +#define ADC_AD0INTEN_ADINTEN5 (0x00000020) +#define ADC_AD0INTEN_ADINTEN6_MASK (0x00000040) +#define ADC_AD0INTEN_ADINTEN6 (0x00000040) +#define ADC_AD0INTEN_ADINTEN7_MASK (0x00000080) +#define ADC_AD0INTEN_ADINTEN7 (0x00000080) +#define ADC_AD0INTEN_ADGINTEN_MASK (0x00000100) +#define ADC_AD0INTEN_ADGINTEN_ENABLE (0x00000100) +#define ADC_AD0INTEN_ADGINTEN_DISABLE (0x00000000) + +/* AD0DR0..7 (A/D Data Registers) + The A/D Data Register hold the result when an A/D conversion is complete, and also + include the flags that indicate when a conversion has been completed and when a + conversion overrun has occurred. */ + +#define ADC_DR_V_MASK (0x0000FFC0) +#define ADC_DR_OVERRUN_MASK (0x40000000) +#define ADC_DR_OVERRUN (0x40000000) +#define ADC_DR_DONE_MASK (0x80000000) +#define ADC_DR_DONE (0x80000000) + +/*############################################################################## +## WDT - Watchdog Timer +##############################################################################*/ + +#define WDT_BASE_ADDRESS (0x40004000) + +#define WDT_WDMOD (*(pREG32 (0x40004000))) // Watchdog mode register +#define WDT_WDTC (*(pREG32 (0x40004004))) // Watchdog timer constant register +#define WDT_WDFEED (*(pREG32 (0x40004008))) // Watchdog feed sequence register +#define WDT_WDTV (*(pREG32 (0x4000400C))) // Watchdog timer value register + +/* WDMOD (Watchdog Mode register) + The WDMOD register controls the operation of the Watchdog through the combination of + WDEN and RESET bits. Note that a watchdog feed must be performed before any + changes to the WDMOD register take effect. */ + +#define WDT_WDMOD_WDEN_DISABLED (0x00000000) // Watchdog enable bit +#define WDT_WDMOD_WDEN_ENABLED (0x00000001) +#define WDT_WDMOD_WDEN_MASK (0x00000001) +#define WDT_WDMOD_WDRESET_DISABLED (0x00000000) // Watchdog reset enable bit +#define WDT_WDMOD_WDRESET_ENABLED (0x00000002) +#define WDT_WDMOD_WDRESET_MASK (0x00000002) +#define WDT_WDMOD_WDTOF (0x00000004) // Watchdog time-out interrupt flag +#define WDT_WDMOD_WDTOF_MASK (0x00000004) // Set when the watchdog times out +#define WDT_WDMOD_WDINT (0x00000008) // Watchdog timer interrupt flag +#define WDT_WDMOD_WDINT_MASK (0x00000008) + +/* WDFEED (Watchdog Feed register) + Writing 0xAA followed by 0x55 to this register will reload the Watchdog timer with the + WDTC value. This operation will also start the Watchdog if it is enabled via the WDMOD + register. Setting the WDEN bit in the WDMOD register is not sufficient to enable the + Watchdog. A valid feed sequence must be completed after setting WDEN before the + Watchdog is capable of generating a reset. Until then, the Watchdog will ignore feed + errors. After writing 0xAA to WDFEED, access to any Watchdog register other than writing + 0x55 to WDFEED causes an immediate reset/interrupt when the Watchdog is enabled. + The reset will be generated during the second PCLK following an incorrect access to a + Watchdog register during a feed sequence. + Interrupts should be disabled during the feed sequence. An abort condition will occur if an + interrupt happens during the feed sequence. */ + +#define WDT_WDFEED_FEED1 (0x000000AA) +#define WDT_WDFEED_FEED2 (0x00000055) + +/*############################################################################## +## Misc. Inline Functions +##############################################################################*/ + +/**************************************************************************/ +/*! + @brief Reverses the bit order of a 32-bit value + + Allows single-cycle reversing of 32-bit values (ASM RBIT) + + @param[in] value + The 32-bit value to reverse + @returns The reversed value +*/ +/**************************************************************************/ +static inline uint32_t RBIT(uint32_t value) { uint32_t result=0; __asm volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); return(result); } + +/**************************************************************************/ +/*! + @brief Causes a system reset and enters the USB Bootloader + + Resets the system using the AIRCR register, and waits in a loop until + reset occurs. The resistor/divider on the LPC1343 Reference Design + Base Board [1] causes the AIRCR reset to enter the bootloader rather + than executing the existing firmware. If you wish to reset and execute + the existing firmware, you need to use the watchdog timer to reset + (see "wdt/wdt.c"). + + [1] http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign.aspx +*/ +/**************************************************************************/ +static inline void __resetBootloader() { __disable_irq(); SCB_AIRCR = SCB_AIRCR_VECTKEY_VALUE | SCB_AIRCR_SYSRESETREQ; while(1); } + +#endif \ No newline at end of file diff --git a/lpc1xxx/LPC11xx_handlers.c b/lpc1xxx/LPC11xx_handlers.c new file mode 100644 index 0000000..2f713e2 --- /dev/null +++ b/lpc1xxx/LPC11xx_handlers.c @@ -0,0 +1,170 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +// The GCC compiler defines the current architecture derived from the -mcpu argument. +// When target cpu is the cortex-m0, it automatically defines __ARM_ARCH_6M__ +#ifndef __ARM_ARCH_6M__ + #error "The target ARM cpu must be Cortex-M0 compatible (-mcpu=cortex-m0)" +#endif + +// Declare a weak alias macro as described in the GCC manual[1][2] +#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f))); +#define SECTION(s) __attribute__ ((section(s))) + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +void irq_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void CAN_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined); +void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined); + +/***************************************************************************** + * Forward undefined fault handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + ****************************************************************************/ + +void fault_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void NMI_Handler(void) WEAK_ALIAS(fault_undefined); +void HardFault_Handler(void) WEAK_ALIAS(fault_undefined); +void MemManage_Handler(void) WEAK_ALIAS(fault_undefined); +void BusFault_Handler(void) WEAK_ALIAS(fault_undefined); +void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined); +void SVCall_Handler(void) WEAK_ALIAS(fault_undefined); +void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined); +void PendSV_Handler(void) WEAK_ALIAS(fault_undefined); +void SysTick_Handler(void) WEAK_ALIAS(fault_undefined); + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +// Prototype the entry values, which are handled by the linker script +extern void* stack_entry; +extern void boot_entry(void); + +// Defined irq vectors using simple c code following the description in a white +// paper from ARM[3] and code example from Simonsson Fun Technologies[4]. +// These vectors are placed at the memory location defined in the linker script +const void *vectors[] SECTION(".irq_vectors") = +{ + // Stack and program reset entry point + &stack_entry, // The initial stack pointer + boot_entry, // The reset handler + + // Various fault handlers + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // MemManage_Handler + BusFault_Handler, // BusFault_Handler + UsageFault_Handler, // UsageFault_Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVCall_Handler, // SVCall handler + DebugMon_Handler, // DebugMon_Handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Wakeup I/O pins handlers + WAKEUP_IRQHandler, // PIO0_0 Wakeup + WAKEUP_IRQHandler, // PIO0_1 Wakeup + WAKEUP_IRQHandler, // PIO0_2 Wakeup + WAKEUP_IRQHandler, // PIO0_3 Wakeup + WAKEUP_IRQHandler, // PIO0_4 Wakeup + WAKEUP_IRQHandler, // PIO0_5 Wakeup + WAKEUP_IRQHandler, // PIO0_6 Wakeup + WAKEUP_IRQHandler, // PIO0_7 Wakeup + WAKEUP_IRQHandler, // PIO0_8 Wakeup + WAKEUP_IRQHandler, // PIO0_9 Wakeup + WAKEUP_IRQHandler, // PIO0_10 Wakeup + WAKEUP_IRQHandler, // PIO0_11 Wakeup + WAKEUP_IRQHandler, // PIO1_0 Wakeup + + // Specific peripheral irq handlers + CAN_IRQHandler, // CAN + SSP1_IRQHandler, // SSP1 + I2C_IRQHandler, // I2C0 + TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0) + TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1) + TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0) + TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1) + SSP0_IRQHandler, // SSP0 + UART_IRQHandler, // UART0 + USB_IRQHandler, // USB IRQ + USB_FIQHandler, // USB FIQ + ADC_IRQHandler, // ADC (A/D Converter) + WDT_IRQHandler, // WDT (Watchdog Timer) + BOD_IRQHandler, // BOD (Brownout Detect) + FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller) + PIOINT3_IRQHandler, // PIO INT3 + PIOINT2_IRQHandler, // PIO INT2 + PIOINT1_IRQHandler, // PIO INT1 + PIOINT0_IRQHandler, // PIO INT0 +}; + +/****************************************************************************** + * References + * [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html + * [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf + * [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php + *****************************************************************************/ + diff --git a/lpc1xxx/LPC13xx_handlers.c b/lpc1xxx/LPC13xx_handlers.c new file mode 100644 index 0000000..9524de6 --- /dev/null +++ b/lpc1xxx/LPC13xx_handlers.c @@ -0,0 +1,193 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +// The GCC compiler defines the current architecture derived from the -mcpu argument. +// When target cpu is the cortex-m3, it automatically defines __ARM_ARCH_7M__ +#ifndef __ARM_ARCH_7M__ + #error "The target ARM cpu must be Cortex-M3 compatible (-mcpu=cortex-m3)" +#endif + +// Declare a weak alias macro as described in the GCC manual[1][2] +#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f))); +#define SECTION(s) __attribute__ ((section(s))) + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +void irq_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void SSP_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined); +void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined); +void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined); + +/***************************************************************************** + * Forward undefined fault handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + ****************************************************************************/ + +void fault_undefined() { + // Do nothing when occured interrupt is not defined, just keep looping + while(1); +} + +void NMI_Handler(void) WEAK_ALIAS(fault_undefined); +void HardFault_Handler(void) WEAK_ALIAS(fault_undefined); +void MemManage_Handler(void) WEAK_ALIAS(fault_undefined); +void BusFault_Handler(void) WEAK_ALIAS(fault_undefined); +void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined); +void SVCall_Handler(void) WEAK_ALIAS(fault_undefined); +void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined); +void PendSV_Handler(void) WEAK_ALIAS(fault_undefined); +void SysTick_Handler(void) WEAK_ALIAS(fault_undefined); + +/****************************************************************************** + * Forward undefined IRQ handlers to an infinite loop function. The Handlers + * are weakly aliased which means that (re)definitions will overide these. + *****************************************************************************/ + +// Prototype the entry values, which are handled by the linker script +extern void* stack_entry; +extern void boot_entry(void); + +// Defined irq vectors using simple c code following the description in a white +// paper from ARM[3] and code example from Simonsson Fun Technologies[4]. +// These vectors are placed at the memory location defined in the linker script +const void *vectors[] SECTION(".irq_vectors") = +{ + // Stack and program reset entry point + &stack_entry, // The initial stack pointer + boot_entry, // The reset handler + + // Various fault handlers + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVCall_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Wakeup I/O pins handlers + WAKEUP_IRQHandler, // PIO0_0 Wakeup + WAKEUP_IRQHandler, // PIO0_1 Wakeup + WAKEUP_IRQHandler, // PIO0_2 Wakeup + WAKEUP_IRQHandler, // PIO0_3 Wakeup + WAKEUP_IRQHandler, // PIO0_4 Wakeup + WAKEUP_IRQHandler, // PIO0_5 Wakeup + WAKEUP_IRQHandler, // PIO0_6 Wakeup + WAKEUP_IRQHandler, // PIO0_7 Wakeup + WAKEUP_IRQHandler, // PIO0_8 Wakeup + WAKEUP_IRQHandler, // PIO0_9 Wakeup + WAKEUP_IRQHandler, // PIO0_10 Wakeup + WAKEUP_IRQHandler, // PIO0_11 Wakeup + WAKEUP_IRQHandler, // PIO1_0 Wakeup + WAKEUP_IRQHandler, // PIO1_1 Wakeup + WAKEUP_IRQHandler, // PIO1_2 Wakeup + WAKEUP_IRQHandler, // PIO1_3 Wakeup + WAKEUP_IRQHandler, // PIO1_4 Wakeup + WAKEUP_IRQHandler, // PIO1_5 Wakeup + WAKEUP_IRQHandler, // PIO1_6 Wakeup + WAKEUP_IRQHandler, // PIO1_7 Wakeup + WAKEUP_IRQHandler, // PIO1_8 Wakeup + WAKEUP_IRQHandler, // PIO1_9 Wakeup + WAKEUP_IRQHandler, // PIO1_10 Wakeup + WAKEUP_IRQHandler, // PIO1_11 Wakeup + WAKEUP_IRQHandler, // PIO2_0 Wakeup + WAKEUP_IRQHandler, // PIO2_1 Wakeup + WAKEUP_IRQHandler, // PIO2_2 Wakeup + WAKEUP_IRQHandler, // PIO2_3 Wakeup + WAKEUP_IRQHandler, // PIO2_4 Wakeup + WAKEUP_IRQHandler, // PIO2_5 Wakeup + WAKEUP_IRQHandler, // PIO2_6 Wakeup + WAKEUP_IRQHandler, // PIO2_7 Wakeup + WAKEUP_IRQHandler, // PIO2_8 Wakeup + WAKEUP_IRQHandler, // PIO2_9 Wakeup + WAKEUP_IRQHandler, // PIO2_10 Wakeup + WAKEUP_IRQHandler, // PIO2_11 Wakeup + WAKEUP_IRQHandler, // PIO3_0 Wakeup + WAKEUP_IRQHandler, // PIO3_1 Wakeup + WAKEUP_IRQHandler, // PIO3_2 Wakeup + WAKEUP_IRQHandler, // PIO3_3 Wakeup + + // Specific peripheral irq handlers + I2C_IRQHandler, // I2C0 + TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0) + TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1) + TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0) + TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1) + SSP_IRQHandler, // SSP0 + UART_IRQHandler, // UART0 + USB_IRQHandler, // USB IRQ + USB_FIQHandler, // USB FIQ + ADC_IRQHandler, // ADC (A/D Converter) + WDT_IRQHandler, // WDT (Watchdog Timer) + BOD_IRQHandler, // BOD (Brownout Detect) + FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller) + PIOINT3_IRQHandler, // PIO INT3 + PIOINT2_IRQHandler, // PIO INT2 + PIOINT1_IRQHandler, // PIO INT1 + PIOINT0_IRQHandler, // PIO INT0 +}; + +/****************************************************************************** + * References + * [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html + * [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html + * [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf + * [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php + *****************************************************************************/ + diff --git a/lpc1xxx/LPC1xxx_startup.c b/lpc1xxx/LPC1xxx_startup.c new file mode 100644 index 0000000..db54ec3 --- /dev/null +++ b/lpc1xxx/LPC1xxx_startup.c @@ -0,0 +1,65 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +// These are defined and created by the linker, locating them in memory +extern unsigned char _etext; +extern unsigned char _data; +extern unsigned char _edata; +extern unsigned char _bss; +extern unsigned char _ebss; + +// Prototype the required startup functions +extern void main(void); + +// The entry point of the application, prepare segments, +// initialize the cpu and execute main() +void boot_entry(void) +{ + register unsigned char *src, *dst; + + // Get physical data address and copy it to sram + src = &_etext; + dst = &_data; + while(dst < &_edata) { + *dst++ = *src++; + } + + // Clear the bss segment + dst = &_bss; + while(dst < &_ebss) { + *dst++ = 0; + } + + // Execute the code at the program entry point + main(); + + // Do nothing when returned from main, just keep looping + while(1); +} diff --git a/lpc1xxx/linkscript.ld b/lpc1xxx/linkscript.ld new file mode 100644 index 0000000..74134f1 --- /dev/null +++ b/lpc1xxx/linkscript.ld @@ -0,0 +1,77 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +sram_top = ORIGIN(sram) + LENGTH(sram); +ENTRY(boot_entry) + +SECTIONS +{ + .text : + { + KEEP(*(.irq_vectors)) + *(.text*) + *(.rodata*) + } > flash + + /* + * More information about Special Section Indexes is available in the + * free "ELF for the ARM Architecture" document from ARM Limited + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf + * + */ + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > flash + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > flash + __exidx_end = .; + + _etext = .; + + .data : AT (__exidx_end) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > sram + + /* zero initialized data */ + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > sram + + end = .; + + /* For GDB compatibility we decrease the top with 16 bytes */ + stack_entry = sram_top - 16; +} diff --git a/lpcrc b/lpcrc new file mode 100644 index 0000000..a6c1aa4 Binary files /dev/null and b/lpcrc differ diff --git a/lpcrc.exe b/lpcrc.exe new file mode 100644 index 0000000..d4ccd6f Binary files /dev/null and b/lpcrc.exe differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..2011970 --- /dev/null +++ b/main.c @@ -0,0 +1,141 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "drivers/sensors/pn532/pn532.h" +#include "drivers/sensors/pn532/pn532_drvr.h" + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. + + Note: CFG_INTERFACE is normally enabled by default. If you wish to + enable the blinking LED code in main, you will need to open + projectconfig.h, comment out "#define CFG_INTERFACE" and + rebuild the project. +*/ +/**************************************************************************/ +int main (void) +{ + #ifdef CFG_INTERFACE + //#error "CFG_INTERFACE must be disabled in projectconfig.h for this demo" + #endif + #if !defined CFG_PRINTF_USBCDC + #error "CFG_PRINTF_USBCDC must be enabled in projectconfig.h for this demo" + #endif + + // Configure cpu and mandatory peripherals + systemInit(); + + // Wait 5 second for someone to open the USB connection for printf + systickDelay(5000); + + // Initialise the PN532 + pn532Init(); + + byte_t response[256]; + size_t responseLen; + pn532_error_t error; + + // Setup command to initialise a single ISO14443A target at 106kbps + byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS }; + + while (1) + { + printf("%s", CFG_PRINTF_NEWLINE); + printf("Wait for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE); + + // Send the command + error = pn532Write(abtCommand, sizeof(abtCommand)); + + // Wait until we get a response or an unexpected error message + do + { + error = pn532Read(response, &responseLen); + systickDelay(25); + } + #ifdef PN532_UART + while (error == PN532_ERROR_RESPONSEBUFFEREMPTY); + #endif + #ifdef PN532_SPI + while ((error == PN532_ERROR_RESPONSEBUFFEREMPTY) || (error = PN532_ERROR_SPIREADYSTATUSTIMEOUT)); + #endif + + // Print the card details if possible + if (!error) + { + /* Response for ISO14443A 106KBPS (Mifare Classic, etc.) + See UM0701-02 section 7.3.5 for more information + + byte Description + ------------- ------------------------------------------ + b7 Tags Found + b8 Tag Number (only one used in this example) + b9..10 SENS_RES + b11 SEL_RES + b12 NFCID Length + b13..NFCIDLen NFCID + + SENS_RES SEL_RES Manufacturer/Card Type NFCID Len + -------- ------- ----------------------- --------- + 00 04 08 NXP Mifare Classic 1K 4 bytes */ + + printf("%s", CFG_PRINTF_NEWLINE); + printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE); + printf("%-12s: ", "NFCID"); + size_t pos; + for (pos=0; pos < response[12]; pos++) + { + printf("%02x ", response[13 + pos]); + } + printf(CFG_PRINTF_NEWLINE); + } + else + { + // Oops .... something bad happened. Check 'error' + printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE); + } + + // Wait at least one second before trying again + systickDelay(1000); + } +} diff --git a/project/cmd_tbl.h b/project/cmd_tbl.h new file mode 100644 index 0000000..e516834 --- /dev/null +++ b/project/cmd_tbl.h @@ -0,0 +1,150 @@ +/**************************************************************************/ +/*! + @file cmd_tbl.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __CMD_TBL_H__ +#define __CMD_TBL_H__ + +#define CMD_COUNT (sizeof(cmd_tbl)/sizeof(cmd_t)) + +#include + +#ifdef CFG_INTERFACE_UART +#include "core/uart/uart.h" +#endif + +// Function prototypes for the command table +void cmd_help(uint8_t argc, char **argv); // handled by core/cmd/cmd.c +void cmd_sysinfo(uint8_t argc, char **argv); + +#ifdef CFG_TFTLCD +void cmd_button(uint8_t argc, char **argv); +void cmd_circle(uint8_t argc, char **argv); +void cmd_clear(uint8_t argc, char **argv); +void cmd_line(uint8_t argc, char **argv); +void cmd_rectangle(uint8_t argc, char **argv); +void cmd_pixel(uint8_t argc, char **argv); +void cmd_progress(uint8_t argc, char **argv); +void cmd_getpixel(uint8_t argc, char **argv); +void cmd_gettext(uint8_t argc, char **argv); +void cmd_calibrate(uint8_t argc, char **argv); +void cmd_orientation(uint8_t argc, char **argv); +void cmd_text(uint8_t argc, char **argv); +void cmd_textw(uint8_t argc, char **argv); +void cmd_tsthreshhold(uint8_t argc, char **argv); +void cmd_tswait(uint8_t argc, char **argv); +#ifdef CFG_SDCARD +void cmd_bmp(uint8_t argc, char **argv); +#endif +#endif + +#ifdef CFG_CHIBI +void cmd_chibi_addr(uint8_t argc, char **argv); +void cmd_chibi_tx(uint8_t argc, char **argv); +#endif + +#ifdef CFG_I2CEEPROM +void cmd_i2ceeprom_read(uint8_t argc, char **argv); +void cmd_i2ceeprom_write(uint8_t argc, char **argv); +void cmd_uart(uint8_t argc, char **argv); +#endif + +#ifdef CFG_LM75B +void cmd_lm75b_gettemp(uint8_t argc, char **argv); +#endif + +#ifdef CFG_SDCARD +void cmd_sd_dir(uint8_t argc, char **argv); +#endif + +#define CMD_NOPARAMS "This command has no parameters" + +/**************************************************************************/ +/*! + Command list for the command-line interpreter and the name of the + corresponding method that handles the command. + + Note that a trailing ',' is required on the last entry, which will + cause a NULL entry to be appended to the end of the table. +*/ +/**************************************************************************/ +cmd_t cmd_tbl[] = +{ + // command name, min args, max args, hidden, function name, command description, syntax + { "?", 0, 0, 0, cmd_help , "Help" , CMD_NOPARAMS }, + { "V", 0, 0, 0, cmd_sysinfo , "System Info" , CMD_NOPARAMS }, + + #ifdef CFG_I2CEEPROM + { "e", 1, 1, 0, cmd_i2ceeprom_read , "EEPROM Read" , "'e '" }, + { "w", 2, 2, 0, cmd_i2ceeprom_write , "EEPROM Write" , "'w '" }, + { "U", 0, 1, 0, cmd_uart , "UART baud rate" , "'U []'" }, + #endif + + #ifdef CFG_TFTLCD + { "b", 7, 99, 0, cmd_button , "Button" , "'b []'" }, + #ifdef CFG_SDCARD + { "B", 3, 3, 0, cmd_bmp , "Bitmap (SD Card)" , "'B '" }, + #endif + { "c", 4, 6, 0, cmd_circle , "Circle" , "'c [ ]'" }, + { "C", 0, 0, 0, cmd_calibrate , "Calibrate Touch Screen" , CMD_NOPARAMS }, + { "F", 0, 1, 0, cmd_clear , "Fill" , "'F []'" }, + { "l", 5, 7, 0, cmd_line , "Line" , "'l [ ]'" }, + { "o", 0, 1, 0, cmd_orientation , "LCD Orientation" , "'o [<0|1>]'" }, + { "p", 3, 3, 0, cmd_pixel , "Draw Pixel" , "'p '" }, + { "P", 9, 9, 0, cmd_progress , "Progress Bar" , "'P <%> '" }, + { "r", 5, 7, 0, cmd_rectangle , "Rectangle" , "'r [ ]'" }, + { "R", 2, 2, 0, cmd_getpixel , "Read Pixel" , "'R '" }, + { "s", 2, 99, 0, cmd_textw , "Text Width" , "'s '" }, + { "t", 5, 99, 0, cmd_text , "Text" , "'t '" }, + { "T", 0, 0, 0, cmd_gettext , "Text Dialogue" , CMD_NOPARAMS }, + { "W", 0, 1, 0, cmd_tswait , "Wait for Touch" , "'W []'" }, + { "x", 0, 1, 0, cmd_tsthreshhold , "Touch Threshold" , "'x [<0..254>]'" }, + #endif + + #ifdef CFG_CHIBI + { "A", 0, 1, 0, cmd_chibi_addr , "Get/Set Node Address" , "'A [<0x0..0xFFFE>]'" }, + { "S", 2, 99, 0, cmd_chibi_tx , "Send Message" , "'S '" }, + #endif + + #ifdef CFG_LM75B + { "m", 0, 0, 0, cmd_lm75b_gettemp , "Temp (C)" , CMD_NOPARAMS }, + #endif + + #ifdef CFG_SDCARD + { "d", 0, 1, 0, cmd_sd_dir , "Dir (SD Card)" , "'d []'" }, + #endif +}; + +#endif \ No newline at end of file diff --git a/project/commands.c b/project/commands.c new file mode 100644 index 0000000..91bce4e --- /dev/null +++ b/project/commands.c @@ -0,0 +1,120 @@ +/**************************************************************************/ +/*! + @file commands.c + @author K. Townsend (microBuilder.eu) + + @brief Common helper-functions for all commands in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include +#include // memset +#include // isdigit, isspace, etc. + +#include "core/cmd/cmd.h" +#include "commands.h" + +/**************************************************************************/ +/*! + @brief Attempts to convert the supplied decimal or hexadecimal + string to the matching 32-bit value. All hexadecimal values + must be preceded by either '0x' or '0X' to be properly parsed. + + @param[in] s + Input string + @param[out] result + Signed 32-bit integer to hold the conversion results + + @section Example + + @code + char *hex = "0xABCD"; + char *dec = "1234"; + + // Convert supplied values to integers + int32_t hexValue, decValue; + getNumber (hex, &hexValue); + getNumber (dec, &decValue); + + @endcode +*/ +/**************************************************************************/ +int getNumber (char *s, int32_t *result) +{ + int32_t value; + uint32_t mustBeHex = FALSE; + uint32_t sgn = 1; + const unsigned char hexToDec [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15}; + + if (!s) + return 0; + + // Check if this is a hexadecimal value + if ((strlen (s) > 2) && (!strncmp (s, "0x", 2) || !strncmp (s, "0X", 2))) + { + mustBeHex = TRUE; + s += 2; + } + + // Check for negative sign + if (!mustBeHex && *s && (*s == '-')) + { + sgn = -1; + s++; + } + + // Try to convert value + for (value = 0; *s; s++) + { + if (mustBeHex && isxdigit ((uint8_t)*s)) + value = (value << 4) | hexToDec [toupper((uint8_t)*s) - '0']; + else if (isdigit ((uint8_t)*s)) + value = (value * 10) + ((uint8_t)*s - '0'); + else + { + printf ("Malformed number. Must be decimal number, or hex value preceeded by '0x'%s", CFG_PRINTF_NEWLINE); + return 0; + } + } + + // Set number to negative value if required + if (!mustBeHex) + value *= sgn; + + *result = value; + + return 1; +} + + + diff --git a/project/commands.h b/project/commands.h new file mode 100644 index 0000000..dd3acd1 --- /dev/null +++ b/project/commands.h @@ -0,0 +1,44 @@ +/**************************************************************************/ +/*! + @file commands.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef __COMMANDS_H__ +#define __COMMANDS_H__ + +#include "projectconfig.h" + +// Method Prototypes +int getNumber (char *s, int32_t *result); + +#endif \ No newline at end of file diff --git a/project/commands/cmd_chibi_addr.c b/project/commands/cmd_chibi_addr.c new file mode 100644 index 0000000..d195262 --- /dev/null +++ b/project/commands/cmd_chibi_addr.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/*! + @file cmd_chibi_addr.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_chibi_addr in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb.h" + #include "drivers/chibi/chb_drvr.h" + +/**************************************************************************/ +/*! + Gets or sets the 16-bit sensor node address. This value can be + anything between 1-65534 (0x0001-0xFFFE), and in decimal or + hexadecimal notation. All hexadecimal values must be preceded by + '0x' or '0X' to be properly interpreted (ex. 0x009F). +*/ +/**************************************************************************/ +void cmd_chibi_addr(uint8_t argc, char **argv) +{ + if (argc > 0) + { + // Try to convert supplied value to an integer + int32_t addr; + getNumber (argv[0], &addr); + + // Check for invalid values (getNumber may complain about this as well) + if (addr <= 0 || addr > 0xFFFF) + { + printf("Invalid Address: 1-65534 or 0x0001-0xFFFE required.%s", CFG_PRINTF_NEWLINE); + return; + } + if (addr == 0xFFFF) + { + printf("Invalid Address: 0xFFFF reserved for broadcast.%s", CFG_PRINTF_NEWLINE); + return; + } + + // Write address to EEPROM and update peripheral control block + chb_set_short_addr((uint16_t)addr); + chb_pcb_t *pcb = chb_get_pcb(); + printf("Address set to: 0x%04X%s", pcb->src_addr, CFG_PRINTF_NEWLINE); + } + else + { + // Display the current address + chb_pcb_t *pcb = chb_get_pcb(); + printf("0x%04X%s", pcb->src_addr, CFG_PRINTF_NEWLINE); + } +} + +#endif diff --git a/project/commands/cmd_chibi_tx.c b/project/commands/cmd_chibi_tx.c new file mode 100644 index 0000000..eb2e43d --- /dev/null +++ b/project/commands/cmd_chibi_tx.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/*! + @file cmd_chibi_tx.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_chibi_tx in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb.h" + #include "drivers/chibi/chb_drvr.h" + +/**************************************************************************/ +/*! + Sends text or data via Chibi + +*/ +/**************************************************************************/ +void cmd_chibi_tx(uint8_t argc, char **argv) +{ + uint8_t i, len, *data_ptr, data[50]; + uint16_t addr; + + // Try to convert supplied address to an integer + int32_t addr32; + getNumber (argv[0], &addr32); + + // Check for invalid values (getNumber may complain about this as well) + if (addr32 <= 0 || addr32 > 0xFFFF) + { + printf("Invalid Address: 1-65534 or 0x0001-0xFFFE required.%s", CFG_PRINTF_NEWLINE); + return; + } + + // Address seems to be OK + addr = (uint16_t)addr32; + + // Get message contents + data_ptr = data; + for (i=0; i + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_I2CEEPROM + #include "drivers/eeprom/eeprom.h" + +/**************************************************************************/ +/*! + Reads a single byte at the supplied EEPROM address +*/ +/**************************************************************************/ +void cmd_i2ceeprom_read(uint8_t argc, char **argv) +{ + uint16_t addr; + uint8_t value; + + // Try to convert supplied address to an integer + int32_t addr32; + getNumber (argv[0], &addr32); + + // Check for invalid values (getNumber may complain about this as well) + if (addr32 < 0 || eepromCheckAddress(addr32)) + { + printf("Address out of range %s", CFG_PRINTF_NEWLINE); + return; + } + + // Address seems to be OK + addr = (uint16_t)addr32; + value = eepromReadU8(addr); + + printf("0x%02X%s", value, CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/cmd_i2ceeprom_write.c b/project/commands/cmd_i2ceeprom_write.c new file mode 100644 index 0000000..0eec71e --- /dev/null +++ b/project/commands/cmd_i2ceeprom_write.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/*! + @file cmd_i2ceeprom_write.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_i2ceeprom_write in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_I2CEEPROM + #include "drivers/eeprom/eeprom.h" + +/**************************************************************************/ +/*! + Writes a single byte at the supplied EEPROM address +*/ +/**************************************************************************/ +void cmd_i2ceeprom_write(uint8_t argc, char **argv) +{ + uint16_t addr; + uint8_t val; + + // Try to convert supplied address to an integer + int32_t addr32; + getNumber (argv[0], &addr32); + + // Check for invalid values (getNumber may complain about this as well) + if (addr32 < 0 || eepromCheckAddress(addr32)) + { + printf("Address out of range %s", CFG_PRINTF_NEWLINE); + return; + } + + // Address seems to be OK + addr = (uint16_t)addr32; + + // Make sure this isn't in the reserved system config space + if (addr <= CFG_EEPROM_RESERVED) + { + printf("ERROR: Reserved address (0x%04X-0x%04X)%s", 0, CFG_EEPROM_RESERVED, CFG_PRINTF_NEWLINE); + return; + } + + // Try to convert supplied data to an integer + int32_t val32; + getNumber (argv[1], &val32); + + // Check for invalid values (getNumber may complain about this as well) + if (val32 < 0 || val32 > 0xFF) + { + printf("Invalid Data: 0-255 or 0x00-0xFF required.%s", CFG_PRINTF_NEWLINE); + return; + } + + // Data seems to be OK + val = (uint8_t)val32; + + // Write data at supplied address + eepromWriteU8(addr, val); + + // Write successful + printf("0x%02X written at 0x%04X%s", val, addr, CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/cmd_lm75b_gettemp.c b/project/commands/cmd_lm75b_gettemp.c new file mode 100644 index 0000000..e0a113a --- /dev/null +++ b/project/commands/cmd_lm75b_gettemp.c @@ -0,0 +1,67 @@ +/**************************************************************************/ +/*! + @file cmd_lm75b_gettemp.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_lm75b_gettemp in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_LM75B + #include "drivers/sensors/lm75b/lm75b.h" + +/**************************************************************************/ +/*! + Gets the current temperature in degrees celsius from the LM75B +*/ +/**************************************************************************/ +void cmd_lm75b_gettemp(uint8_t argc, char **argv) +{ + int32_t temp = 0; + + // Get the current temperature (in 0.125°C units) + lm75bGetTemperature(&temp); + + // Multiply value by 125 for fixed-point math (0.125°C per unit) + temp *= 125; + + // Use modulus operator to display decimal value + printf("%d.%d C%s", temp / 1000, temp % 1000, CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/cmd_sd_dir.c b/project/commands/cmd_sd_dir.c new file mode 100644 index 0000000..49fe6a5 --- /dev/null +++ b/project/commands/cmd_sd_dir.c @@ -0,0 +1,144 @@ +/**************************************************************************/ +/*! + @file cmd_sd_dir.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_sd_dir in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_SDCARD + #include "core/timer32/timer32.h" + #include "core/ssp/ssp.h" + #include "drivers/fatfs/diskio.h" + #include "drivers/fatfs/ff.h" + + static FILINFO Finfo; + static FATFS Fatfs[1]; + +/**************************************************************************/ +/*! + sd 'dir' command handler + + This demonstrates how to initialise the SD card, read the contents + of a directory (including checking if an entry is a folder or a file), + and checking the amount of freespace on available on the disk. +*/ +/**************************************************************************/ +void cmd_sd_dir(uint8_t argc, char **argv) +{ + char* path; + + // Display root folder by default + path = argc > 0 ? argv[0] : "/"; + + // Initialise SD Card + DSTATUS stat; + stat = disk_initialize(0); + if (stat & STA_NOINIT) + { + printf("SD init failed%s", CFG_PRINTF_NEWLINE); + } + if (stat & STA_NODISK) + { + printf("No SD card%s", CFG_PRINTF_NEWLINE); + } + if (stat == 0) + { + BYTE res; + DIR dir; + + // Try to mount drive + res = f_mount(0, &Fatfs[0]); + if (res != FR_OK) + { + printf("Failed to mount partition%s" , CFG_PRINTF_NEWLINE); + } + if (res == FR_OK) + { + res = f_opendir(&dir, path); + if (res) + { + printf("Failed to open '%s' %s", path, CFG_PRINTF_NEWLINE); + return; + } + + // Display directory name + printf("%s Contents of %s %s%s", CFG_PRINTF_NEWLINE, path, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE); + printf(" %-25s %12s %s", "Filename", "Size", CFG_PRINTF_NEWLINE); + printf(" %-25s %12s %s", "--------", "----", CFG_PRINTF_NEWLINE); + + // Read directory contents + int folderBytes = 0; + for(;;) + { + res = f_readdir(&dir, &Finfo); + if ((res != FR_OK) || !Finfo.fname[0]) break; + #if _USE_LFN == 0 + if (Finfo.fattrib & AM_DIR) + printf(" %-25s %s", (char *)&Finfo.fname[0], CFG_PRINTF_NEWLINE); + else + printf(" %-25s %12d Bytes %s", (char *)&Finfo.fname[0], (int)(Finfo.fsize), CFG_PRINTF_NEWLINE); + folderBytes += Finfo.fsize; + #else + // ToDo + #endif + } + + // Display folder size + printf("%s", CFG_PRINTF_NEWLINE); + printf(" %-25s %12d KB %s", "Folder Size: ", (int)(folderBytes / 1024), CFG_PRINTF_NEWLINE); + + // Get free disk space (only available if FATFS was compiled with _FS_MINIMIZE set to 0) + #if _FS_MINIMIZE == 0 && _FS_READONLY == 0 + FATFS *fs = &Fatfs[0]; + DWORD clust; + + // Get free clusters + res = f_getfree("0:", &clust, &fs); + + // Display total and free space + printf(" %-25s %12d KB %s", "Disk Size: ", (int)((DWORD)(fs->max_clust - 2) * fs->csize / 2), CFG_PRINTF_NEWLINE); + printf(" %-25s %12d KB %s", "Space Available: ", (int)(clust * fs->csize / 2), CFG_PRINTF_NEWLINE); + #endif + } + } +} + +#endif diff --git a/project/commands/cmd_sysinfo.c b/project/commands/cmd_sysinfo.c new file mode 100644 index 0000000..36b66e9 --- /dev/null +++ b/project/commands/cmd_sysinfo.c @@ -0,0 +1,126 @@ +/**************************************************************************/ +/*! + @file cmd_sysinfo.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_sysinfo in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "core/systick/systick.h" +#include "core/iap/iap.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb.h" + #include "drivers/chibi/chb_drvr.h" +#endif + +#ifdef CFG_PRINTF_UART + #include "core/uart/uart.h" +#endif + +#ifdef CFG_LM75B + #include "drivers/sensors/lm75b/lm75b.h" +#endif + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" +#endif + +#ifdef CFG_SDCARD + #include "core/gpio/gpio.h" +#endif + +/**************************************************************************/ +/*! + 'sysinfo' command handler +*/ +/**************************************************************************/ +void cmd_sysinfo(uint8_t argc, char **argv) +{ + IAP_return_t iap_return; + + printf("%-25s : %d.%d MHz %s", "System Clock", CFG_CPU_CCLK / 1000000, CFG_CPU_CCLK % 1000000, CFG_PRINTF_NEWLINE); + printf("%-25s : v%d.%d.%d %s", "Firmware", CFG_FIRMWARE_VERSION_MAJOR, CFG_FIRMWARE_VERSION_MINOR, CFG_FIRMWARE_VERSION_REVISION, CFG_PRINTF_NEWLINE); + + // 128-bit MCU Serial Number + iap_return = iapReadSerialNumber(); + if(iap_return.ReturnCode == 0) + { + printf("%-25s : %08X %08X %08X %08X %s", "Serial Number", iap_return.Result[0],iap_return.Result[1],iap_return.Result[2],iap_return.Result[3], CFG_PRINTF_NEWLINE); + } + + // CLI and buffer Settings + #ifdef CFG_INTERFACE + printf("%-25s : %d bytes %s", "Max CLI Command", CFG_INTERFACE_MAXMSGSIZE, CFG_PRINTF_NEWLINE); + #endif + + #ifdef CFG_PRINTF_UART + uart_pcb_t *pcb = uartGetPCB(); + printf("%-25s : %d %s", "UART Baud Rate", pcb->baudrate, CFG_PRINTF_NEWLINE); + #endif + + // TFT LCD Settings (if CFG_TFTLCD enabled) + #ifdef CFG_TFTLCD + printf("%-25s : %d %s", "LCD Width", (int)lcdGetWidth(), CFG_PRINTF_NEWLINE); + printf("%-25s : %d %s", "LCD Height", (int)lcdGetHeight(), CFG_PRINTF_NEWLINE); + #endif + + // Wireless Settings (if CFG_CHIBI enabled) + #ifdef CFG_CHIBI + chb_pcb_t *pcb = chb_get_pcb(); + printf("%-25s : %s %s", "Wireless", "AT86RF212", CFG_PRINTF_NEWLINE); + printf("%-25s : 0x%04X %s", "802.15.4 PAN ID", CFG_CHIBI_PANID, CFG_PRINTF_NEWLINE); + printf("%-25s : 0x%04X %s", "802.15.4 Node Address", pcb->src_addr, CFG_PRINTF_NEWLINE); + printf("%-25s : %d %s", "802.15.4 Channel", CFG_CHIBI_CHANNEL, CFG_PRINTF_NEWLINE); + #endif + + // System Uptime (based on systick timer) + printf("%-25s : %u s %s", "System Uptime", (unsigned int)systickGetSecondsActive(), CFG_PRINTF_NEWLINE); + + // System Temperature (if LM75B Present) + #ifdef CFG_LM75B + int32_t temp = 0; + lm75bGetTemperature(&temp); + temp *= 125; + printf("%-25s : %d.%d C %s", "Temperature", temp / 1000, temp % 1000, CFG_PRINTF_NEWLINE); + #endif + + #ifdef CFG_SDCARD + printf("%-25s : %s %s", "SD Card Present", gpioGetValue(CFG_SDCARD_CDPORT, CFG_SDCARD_CDPIN) ? "True" : "False", CFG_PRINTF_NEWLINE); + #endif +} diff --git a/project/commands/cmd_uart.c b/project/commands/cmd_uart.c new file mode 100644 index 0000000..8e634f4 --- /dev/null +++ b/project/commands/cmd_uart.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/*! + @file cmd_uart.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_uart in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_I2CEEPROM + #include "drivers/eeprom/eeprom.h" + #include "core/uart/uart.h" + +/**************************************************************************/ +/*! + Gets or sets the UART speed from EEPROM. +*/ +/**************************************************************************/ +void cmd_uart(uint8_t argc, char **argv) +{ + if (argc > 0) + { + // Try to convert supplied value to an integer + int32_t speed; + getNumber (argv[0], &speed); + + // Check for invalid values (getNumber may complain about this as well) + if (speed < 9600 || speed > 115200) + { + printf("Invalid baud rate: 9600-115200 required.%s", CFG_PRINTF_NEWLINE); + return; + } + + // Write baud rate to EEPROM and reinitialise UART if using it + printf("Setting UART to: %d%s", (int)speed, CFG_PRINTF_NEWLINE); + eepromWriteU32(CFG_EEPROM_UART_SPEED, speed); + #ifdef CFG_PRINTF_UART + uartInit(speed); + #endif + } + else + { + // Display the current baud rate + #ifdef CFG_PRINTF_UART + uart_pcb_t *pcb = uartGetPCB(); + printf("%d%s", pcb->baudrate, CFG_PRINTF_NEWLINE); + #else + printf("UART not initialised (using USBCDC)%s", CFG_PRINTF_NEWLINE); + #endif + } +} + +#endif diff --git a/project/commands/drawing/cmd_bmp.c b/project/commands/drawing/cmd_bmp.c new file mode 100644 index 0000000..4ae5423 --- /dev/null +++ b/project/commands/drawing/cmd_bmp.c @@ -0,0 +1,99 @@ +/**************************************************************************/ +/*! + @file cmd_bmp.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_bmp in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#if defined CFG_TFTLCD && defined CFG_SDCARD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a bitmap image on the LCD. +*/ +/**************************************************************************/ +void cmd_bmp(uint8_t argc, char **argv) +{ + int32_t x, y; + char* filename; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + filename = argv[2]; + + // Render image + bmp_error_t error; + error = drawBitmapImage(x, y, filename); + + switch (error) + { + case BMP_ERROR_SDINITFAIL: + printf("SD Init Failed%s", CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_FILENOTFOUND: + printf("File Not Found: '%s'%s", filename, CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_UNABLETOCREATEFILE: + printf("Unable to create file: '%s'%s", filename, CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_NOTABITMAP: + printf("Not a Bitmap: '%s'%s", filename, CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_INVALIDBITDEPTH: + printf("Not a 24-Bit Image%s", CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_INVALIDDIMENSIONS: + printf("Image Exceeds %d x %d Pixels%s", lcdGetWidth(), lcdGetHeight(), CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_COMPRESSEDDATA: + printf("Compressed Images Unsupported%s", CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_PREMATUREEOF: + printf("Premature EOF%s", CFG_PRINTF_NEWLINE); + break; + case BMP_ERROR_NONE: + break; + } +} + +#endif diff --git a/project/commands/drawing/cmd_button.c b/project/commands/drawing/cmd_button.c new file mode 100644 index 0000000..98d376f --- /dev/null +++ b/project/commands/drawing/cmd_button.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/*! + @file cmd_buton.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_button in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/tft/touchscreen.h" + #include "drivers/lcd/tft/fonts/dejavusans9.h" + +/**************************************************************************/ +/*! + Displays a button on the LCD with or without text. + + Ex.: "btn 10 10 220 35 1 This is a test" will display a 220x35 pixel + button in the 'pressed' state (arg 5 = 1) starting at pixel 10, 10 with + 'This is a test' rendered on the button. +*/ +/**************************************************************************/ +void cmd_button(uint8_t argc, char **argv) +{ + int32_t x, y, w, h, border, fill, font; + + // ToDo: Validate data! + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + getNumber (argv[2], &w); + getNumber (argv[3], &h); + getNumber (argv[4], &border); + getNumber (argv[5], &fill); + getNumber (argv[6], &font); + + if (argc == 7) + { + // Render the button with no text + drawButton(x, y, w, h, &dejaVuSans9ptFontInfo, 7, (uint16_t)border, (uint16_t)fill, (uint16_t)font, NULL); + } + else + { + // Get text contents + uint8_t i, len, *data_ptr, data[50]; + data_ptr = data; + for (i = 0; i < argc - 7; i++) + { + len = strlen(argv[i + 7]); + strcpy((char *)data_ptr, (char *)argv[i + 7]); + data_ptr += len; + *data_ptr++ = ' '; + } + *data_ptr++ = '\0'; + + // Render the button with text + drawButton(x, y, w, h, &dejaVuSans9ptFontInfo, 7, (uint16_t)border, (uint16_t)fill, (uint16_t)font, (char *)&data); + } +} + +#endif diff --git a/project/commands/drawing/cmd_calibrate.c b/project/commands/drawing/cmd_calibrate.c new file mode 100644 index 0000000..93316b7 --- /dev/null +++ b/project/commands/drawing/cmd_calibrate.c @@ -0,0 +1,63 @@ +/**************************************************************************/ +/*! + @file cmd_calibrate.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_calibrate in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#if defined CFG_TFTLCD + #include "drivers/lcd/tft/touchscreen.h" + +/**************************************************************************/ +/*! + Starts the touch-screen calibration process. +*/ +/**************************************************************************/ +void cmd_calibrate(uint8_t argc, char **argv) +{ + printf("Starting touch-screen calibration%s", CFG_PRINTF_NEWLINE); + + // Run through the calibration process + tsCalibrate(); + + printf("Calibration complete%s", CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/drawing/cmd_circle.c b/project/commands/drawing/cmd_circle.c new file mode 100644 index 0000000..9eb1227 --- /dev/null +++ b/project/commands/drawing/cmd_circle.c @@ -0,0 +1,102 @@ +/**************************************************************************/ +/*! + @file cmd_circle.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_circle in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a circle on the LCD. +*/ +/**************************************************************************/ +void cmd_circle(uint8_t argc, char **argv) +{ + int32_t x, y, r, c, filled, border; + filled = 0; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + getNumber (argv[2], &r); + getNumber (argv[3], &c); + if (argc >= 5) + { + getNumber (argv[4], &filled); + } + if (argc == 6) + { + getNumber (argv[5], &border); + if (border < 0 || border > 0xFFFF) + { + printf("Invalid Border Color%s", CFG_PRINTF_NEWLINE); + return; + } + } + + // ToDo: Validate data! + if (c < 0 || c > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + if (r < 1) + { + printf("Invalid Radius%s", CFG_PRINTF_NEWLINE); + return; + } + + if (filled) + drawCircleFilled(x, y, r, (uint16_t)c); + else + drawCircle(x, y, r, (uint16_t)c); + + // Draw border if requested + if (argc == 6) + { + drawCircle(x, y, r, (uint16_t)border); + } +} + +#endif diff --git a/project/commands/drawing/cmd_clear.c b/project/commands/drawing/cmd_clear.c new file mode 100644 index 0000000..50ef287 --- /dev/null +++ b/project/commands/drawing/cmd_clear.c @@ -0,0 +1,74 @@ +/**************************************************************************/ +/*! + @file cmd_clear.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_clear in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Fills the LCD with the supplied RGB565 color +*/ +/**************************************************************************/ +void cmd_clear(uint8_t argc, char **argv) +{ + int32_t col = 0; + if (argc > 0) + { + // Try to convert supplied value to an integer + getNumber (argv[0], &col); + + // Check for invalid values (getNumber may complain about this as well) + if (col < 0 || col > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + } + + // Fill the screen + drawFill((uint16_t)col); +} + +#endif diff --git a/project/commands/drawing/cmd_gettext.c b/project/commands/drawing/cmd_gettext.c new file mode 100644 index 0000000..8f41386 --- /dev/null +++ b/project/commands/drawing/cmd_gettext.c @@ -0,0 +1,64 @@ +/**************************************************************************/ +/*! + @file cmd_gettext.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_gettext in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#if defined CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/tft/touchscreen.h" + #include "drivers/lcd/tft/dialogues/alphanumeric.h" + +/**************************************************************************/ +/*! + Displays an alpha-numeric input dialogue on the TFT LCD screen. +*/ +/**************************************************************************/ +void cmd_gettext(uint8_t argc, char **argv) +{ + // Print results from an alpha-numeric dialogue + char* results = alphaShowDialogue(); + drawFill(COLOR_BLACK); + printf("%s%s", results, CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/drawing/cmd_line.c b/project/commands/drawing/cmd_line.c new file mode 100644 index 0000000..2f9ed53 --- /dev/null +++ b/project/commands/drawing/cmd_line.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/*! + @file cmd_line.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_line in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a line on the LCD. +*/ +/**************************************************************************/ +void cmd_line(uint8_t argc, char **argv) +{ + int32_t x1, y1, x2, y2, c, empty, solid; + + // Convert supplied parameters + getNumber (argv[0], &x1); + getNumber (argv[1], &y1); + getNumber (argv[2], &x2); + getNumber (argv[3], &y2); + getNumber (argv[4], &c); + if (argc > 5) + { + getNumber (argv[5], &empty); + getNumber (argv[6], &solid); + } + else + { + empty = 0; + solid = 1; + } + + // ToDo: Validate data! + if (c < 0 || c > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + + drawLineDotted(x1, y1, x2, y2, empty, solid, (uint16_t)c); +} + +#endif diff --git a/project/commands/drawing/cmd_orientation.c b/project/commands/drawing/cmd_orientation.c new file mode 100644 index 0000000..07ac9b3 --- /dev/null +++ b/project/commands/drawing/cmd_orientation.c @@ -0,0 +1,83 @@ +/**************************************************************************/ +/*! + @file cmd_orientation.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_orientation in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Changes the LCD orientation +*/ +/**************************************************************************/ +void cmd_orientation(uint8_t argc, char **argv) +{ + int32_t value; + + if (argc == 0) + { + printf("%d%s", lcdGetOrientation(), CFG_PRINTF_NEWLINE); + return; + } + + // Convert supplied parameters + getNumber (argv[0], &value); + + switch (value) + { + case 0: + lcdSetOrientation(LCD_ORIENTATION_PORTRAIT); + break; + case 1: + lcdSetOrientation(LCD_ORIENTATION_LANDSCAPE); + break; + default: + printf("Invalid value: Enter 0 or 1%s", CFG_PRINTF_NEWLINE); + return; + } + + return; +} + +#endif diff --git a/project/commands/drawing/cmd_pixel.c b/project/commands/drawing/cmd_pixel.c new file mode 100644 index 0000000..9aeffb8 --- /dev/null +++ b/project/commands/drawing/cmd_pixel.c @@ -0,0 +1,92 @@ +/**************************************************************************/ +/*! + @file cmd_pixel.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_pixel in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a single pixel on the LCD. +*/ +/**************************************************************************/ +void cmd_pixel(uint8_t argc, char **argv) +{ + int32_t x, y, c; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + getNumber (argv[2], &c); + + // ToDo: Validate data! + if (c < 0 || c > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + + drawPixel(x, y, (uint16_t)c); +} + +/**************************************************************************/ +/*! + Gets a single pixel from the LCD. +*/ +/**************************************************************************/ +void cmd_getpixel(uint8_t argc, char **argv) +{ + int32_t x, y; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + + uint16_t value = lcdGetPixel(x, y); + + // Output the results + printf("%d%s", value, CFG_PRINTF_NEWLINE); +} + +#endif diff --git a/project/commands/drawing/cmd_progress.c b/project/commands/drawing/cmd_progress.c new file mode 100644 index 0000000..40c1b27 --- /dev/null +++ b/project/commands/drawing/cmd_progress.c @@ -0,0 +1,85 @@ +/**************************************************************************/ +/*! + @file cmd_progress.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_progress in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a progress bar on the LCD. +*/ +/**************************************************************************/ +void cmd_progress(uint8_t argc, char **argv) +{ + int32_t x, y, w, h, percent, border, borderfill, progressborder, progressfill; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + getNumber (argv[2], &w); + getNumber (argv[3], &h); + getNumber (argv[4], &percent); + getNumber (argv[5], &border); + getNumber (argv[6], &borderfill); + getNumber (argv[7], &progressborder); + getNumber (argv[8], &progressfill); + + // ToDo: Validate data! + if (border < 0 || border > 0xFFFF || borderfill < 0 || borderfill > 0xFFFF || progressborder < 0 || progressborder > 0xFFFF || progressfill < 0 || progressfill > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + if (percent < 0 || percent > 100) + { + printf("Invalid Percentage%s", CFG_PRINTF_NEWLINE); + return; + } + + // Draw the progress bar (always use rounded corners for simplicity sake) + drawProgressBar(x, y, w, h, DRAW_ROUNDEDCORNERS_ALL, DRAW_ROUNDEDCORNERS_ALL, border, borderfill, progressborder, progressfill, percent); +} + +#endif diff --git a/project/commands/drawing/cmd_rectangle.c b/project/commands/drawing/cmd_rectangle.c new file mode 100644 index 0000000..581d864 --- /dev/null +++ b/project/commands/drawing/cmd_rectangle.c @@ -0,0 +1,97 @@ +/**************************************************************************/ +/*! + @file cmd_rectangle.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_rectangle in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + +/**************************************************************************/ +/*! + Displays a rectangle on the LCD. +*/ +/**************************************************************************/ +void cmd_rectangle(uint8_t argc, char **argv) +{ + int32_t x1, y1, x2, y2, c, filled, border; + filled = 0; + + // Convert supplied parameters + getNumber (argv[0], &x1); + getNumber (argv[1], &y1); + getNumber (argv[2], &x2); + getNumber (argv[3], &y2); + getNumber (argv[4], &c); + if (argc >= 6) + { + getNumber (argv[5], &filled); + } + if (argc == 7) + { + getNumber (argv[6], &border); + if (border < 0 || border > 0xFFFF) + { + printf("Invalid Border Color%s", CFG_PRINTF_NEWLINE); + return; + } + } + + // ToDo: Validate data! + if (c < 0 || c > 0xFFFF) + { + printf("Invalid Color%s", CFG_PRINTF_NEWLINE); + return; + } + + if (filled) + drawRectangleFilled(x1, y1, x2, y2, (uint16_t)c); + else + drawRectangle(x1, y1, x2, y2, (uint16_t)c); + + if (argc == 7) + { + drawRectangle(x1, y1, x2, y2, (uint16_t)border); + } +} + +#endif diff --git a/project/commands/drawing/cmd_text.c b/project/commands/drawing/cmd_text.c new file mode 100644 index 0000000..ac3bc7c --- /dev/null +++ b/project/commands/drawing/cmd_text.c @@ -0,0 +1,84 @@ +/**************************************************************************/ +/*! + @file cmd_text.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_text in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/tft/fonts/dejavusans9.h" + +/**************************************************************************/ +/*! + Displays the supplied text on the LCD. +*/ +/**************************************************************************/ +void cmd_text(uint8_t argc, char **argv) +{ + int32_t x, y, color; + int32_t font; + uint8_t i, len; + char *data_ptr, data[80]; + + // Convert supplied parameters + getNumber (argv[0], &x); + getNumber (argv[1], &y); + getNumber (argv[2], &color); + getNumber (argv[3], &font); + + // Get message contents + data_ptr = data; + for (i=0; i +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/drawing.h" + #include "drivers/lcd/tft/fonts/dejavusans9.h" + +/**************************************************************************/ +/*! + Returns the width of the supplied text in pixels. +*/ +/**************************************************************************/ +void cmd_textw(uint8_t argc, char **argv) +{ + int32_t font; + uint8_t i, len; + char *data_ptr, data[80]; + + // Convert supplied parameters + getNumber (argv[0], &font); + + // Get message contents + data_ptr = data; + for (i=0; i +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/eeprom/eeprom.h" + #include "drivers/lcd/tft/touchscreen.h" + +/**************************************************************************/ +/*! + Gets or sets the touch screen 'touch event' threshhold +*/ +/**************************************************************************/ +void cmd_tsthreshhold(uint8_t argc, char **argv) +{ + int32_t input; + uint8_t value; + + if (argc == 0) + { + // Display default threshold (from projectconfig.h) + value = tsGetThreshhold(); + printf("%u%s", value, CFG_PRINTF_NEWLINE); + return; + } + + // Convert supplied parameters + getNumber (argv[0], &input); + if ((input < 0) || (input > 254)) + { + printf("Invalid value: Enter 0..254%s", CFG_PRINTF_NEWLINE); + return; + } + + // Store value in EEPROM and update the TS + tsSetThreshhold((uint8_t)input); + value = tsGetThreshhold(); + printf("Set to %u%s", (uint8_t)value, CFG_PRINTF_NEWLINE); + return; +} + +#endif diff --git a/project/commands/drawing/cmd_tswait.c b/project/commands/drawing/cmd_tswait.c new file mode 100644 index 0000000..6a75183 --- /dev/null +++ b/project/commands/drawing/cmd_tswait.c @@ -0,0 +1,94 @@ +/**************************************************************************/ +/*! + @file cmd_tswait.c + @author K. Townsend (microBuilder.eu) + + @brief Code to execute for cmd_tswait in the 'core/cmd' + command-line interpretter. + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include + +#include "projectconfig.h" +#include "core/cmd/cmd.h" +#include "project/commands.h" // Generic helper functions + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/touchscreen.h" + +/**************************************************************************/ +/*! + Waits for a touch screen event and returns the co-ordinates +*/ +/**************************************************************************/ +void cmd_tswait(uint8_t argc, char **argv) +{ + tsTouchData_t data; + int32_t delay; + int32_t error = 0; + + if (argc == 1) + { + getNumber (argv[0], &delay); + } + else + { + delay = 0; + } + + // Validate delay + if (delay < 0) + { + printf("Invalid timeout%s", CFG_PRINTF_NEWLINE); + return; + } + + // Blocking delay until a valid touch event occurs + error = tsWaitForEvent(&data, delay > 0 ? (uint32_t)delay : 0); + + if (error == TS_ERROR_NONE) + { + // A valid touch event occurred ... parse data + printf("%d, %d%s",(int)data.xlcd, (int)data.ylcd, CFG_PRINTF_NEWLINE); + } + else + { + // Display error code + printf("%d %s", (int)error, CFG_PRINTF_NEWLINE); + } + + return; +} + +#endif diff --git a/project/readme.txt b/project/readme.txt new file mode 100644 index 0000000..c2ff73d --- /dev/null +++ b/project/readme.txt @@ -0,0 +1,32 @@ +Project Folder +============================================================================== +All project-specific files should be stored in the /project folder to try to +keep the generic HW-level code and drivers seperate from the business logic +of your individual project. This makes it easier to reuse your code in other +projects, and also update the drivers and HW-level code if newer version of +these common-files become available. + +FOLDERS +============================================================================== +commands/ Code to implements specific commands for the + command-line interface. Requires CFG_INTERFACE + to be enabled in projectconfig.h. Generally, + each command will be stored in a seperate file + (ex.: "command/cmd_hello.c"), though this isn't + a strict requirement and you may wish to store + multiple related commands in one .c file, such + as 'cmds_graphics.c' etc. + +documentation/ Project-specific documentation is stored here + +FILES +============================================================================== +cmd_tbl.h Contains the master command list for the + command-line interface if CFG_INTERFACE is + enabled in projectconfig.h. All commands + must be present in this list to be properly + handled by the CLI. + +commands.c Common helper functions for the command-line + interface. + diff --git a/projectconfig.h b/projectconfig.h new file mode 100644 index 0000000..489064d --- /dev/null +++ b/projectconfig.h @@ -0,0 +1,884 @@ +/**************************************************************************/ +/*! + @file projectconfig.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _PROJECTCONFIG_H_ +#define _PROJECTCONFIG_H_ + +#include "lpc134x.h" +#include "sysdefs.h" + +/*========================================================================= + BOARD SELECTION + + Because several boards use this code library with sometimes slightly + different pin configuration, you will need to specify which board you + are using by enabling one of the following definitions. The code base + will then try to configure itself accordingly for that board. + -----------------------------------------------------------------------*/ + // #define CFG_BRD_LPC1343_REFDESIGN + #define CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_BRD_LPC1343_802154USBSTICK +/*=========================================================================*/ + + +/************************************************************************** + PIN USAGE + ----------------------------------------------------------------------- + This table tries to give an indication of which GPIO pins and + peripherals are used by the available drivers and SW examples. Only + dedicated GPIO pins available on the LPC1343 Reference Board are shown + below. Any unused peripheral blocks like I2C, SSP, ADC, etc., can + also be used as GPIO if they are available. + + PORT 1 PORT 2 PORT 3 + ========= ================= ======= + 8 9 10 11 1 2 3 4 5 6 7 8 9 0 1 2 3 + + SDCARD . . . . . . . . . . . . . X . . . + PWM . X . . . . . . . . . . . . . . . + STEPPER . . . . . . . . . . . . . X X X X + CHIBI X X X . . . . . . . . . . . . . . + ILI9325/8 X X X X X X X X X X X X X . . . X + ST7565 X X X X X X X X X X X X X . . . X + ST7735 . . . . X X X X X X . . . . . . . + SSD1306 . . . . X X X . X X . . . . . . . + MCP121 . . . . . . . . . . . . . . X . . + + TIMERS SSP ADC UART + ====================== === ======= ==== + 16B0 16B1 32B0 32B1 0 0 1 2 3 0 + + SDCARD . . . . X . . . . . + PWM . X . . . . . . . . + PMU [1] . . X . . . . . . . + USB . . . X . . . . . . + STEPPER . . X . . . . . . . + CHIBI x . . . X . . . . . + ILI9325/8 . . . . . X X X X . + ST7565 . . . . . X X X X . + ST7535 . . . . . . . . . . + SSD1306 . . . . . . . . . . + INTERFACE . . . . . . . . . X[2] + + [1] PMU uses 32-bit Timer 0 for SW wakeup from deep-sleep. This timer + can safely be used by other peripherals, but may need to be + reconfigured when you wakeup from deep-sleep. + [2] INTERFACE can be configured to use either USBCDC or UART + + **************************************************************************/ + + +/*========================================================================= + FIRMWARE VERSION SETTINGS + -----------------------------------------------------------------------*/ + #define CFG_FIRMWARE_VERSION_MAJOR (0) + #define CFG_FIRMWARE_VERSION_MINOR (9) + #define CFG_FIRMWARE_VERSION_REVISION (2) +/*=========================================================================*/ + + +/*========================================================================= + CORE CPU SETTINGS + ----------------------------------------------------------------------- + + CFG_CPU_CCLK Value is for reference only. 'core/cpu/cpu.c' must + be modified to change the clock speed, but the value + should be indicated here since CFG_CPU_CCLK is used by + other peripherals to determine timing. + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_CPU_CCLK (72000000) // 1 tick = 13.88nS + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_CPU_CCLK (72000000) // 1 tick = 13.88nS + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_CPU_CCLK (72000000) // 1 tick = 13.88nS + #endif +/*=========================================================================*/ + + +/*========================================================================= + SYSTICK TIMER + ----------------------------------------------------------------------- + + CFG_SYSTICK_DELAY_IN_MS The number of milliseconds between each tick + of the systick timer. + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_SYSTICK_DELAY_IN_MS (1) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_SYSTICK_DELAY_IN_MS (1) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_SYSTICK_DELAY_IN_MS (1) + #endif +/*=========================================================================*/ + + +/*========================================================================= + UART + ----------------------------------------------------------------------- + + CFG_UART_BAUDRATE The default UART speed. This value is used + when initialising UART, and should be a + standard value like 57600, 9600, etc. + NOTE: This value may be overridden if + another value is stored in EEPROM! + CFG_UART_BUFSIZE The length in bytes of the UART RX FIFO. This + will determine the maximum number of received + characters to store in memory. + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_UART_BAUDRATE (115200) + #define CFG_UART_BUFSIZE (512) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_UART_BAUDRATE (115200) + #define CFG_UART_BUFSIZE (512) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_UART_BAUDRATE (115200) + #define CFG_UART_BUFSIZE (512) + #endif +/*=========================================================================*/ + + +/*========================================================================= + SSP + ----------------------------------------------------------------------- + + CFG_SSP0_SCKPIN_2_11 Indicates which pin should be used for SCK0 + CFG_SSP0_SCKPIN_0_6 + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_SSP0_SCKPIN_2_11 + // #define CFG_SSP0_SCKPIN_0_6 + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_SSP0_SCKPIN_2_11 + // #define CFG_SSP0_SCKPIN_0_6 + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_SSP0_SCKPIN_2_11 + #define CFG_SSP0_SCKPIN_0_6 + #endif +/*=========================================================================*/ + + +/*========================================================================= + ON-BOARD LED + ----------------------------------------------------------------------- + + CFG_LED_PORT The port for the on board LED + CFG_LED_PIN The pin for the on board LED + CFG_LED_ON The pin state to turn the LED on (0 = low, 1 = high) + CFG_LED_OFF The pin state to turn the LED off (0 = low, 1 = high) + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_LED_PORT (2) + #define CFG_LED_PIN (10) + #define CFG_LED_ON (0) + #define CFG_LED_OFF (1) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_LED_PORT (2) + #define CFG_LED_PIN (10) + #define CFG_LED_ON (0) + #define CFG_LED_OFF (1) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_LED_PORT (3) + #define CFG_LED_PIN (2) + #define CFG_LED_ON (0) + #define CFG_LED_OFF (1) + #endif +/*=========================================================================*/ + + +/*========================================================================= + MICRO-SD CARD + ----------------------------------------------------------------------- + + CFG_SDCARD If this field is defined SD Card and FAT32 + file system support will be included + CFG_SDCARD_READONLY If this is set to 1, all commands to + write to the SD card will be removed + saving some flash space. + CFG_SDCARD_CDPORT The card detect port number + CFG_SDCARD_CDPIN The card detect pin number + + NOTE: All config settings for FAT32 are defined + in ffconf.h + + BENCHMARK: With SPI set to 6.0MHz, FATFS can read + ~300KB/s (w/512 byte read buffer) + + PIN LAYOUT: The pin layout that is used by this driver + can be seen in the following schematic: + /tools/schematics/Breakout_TFTLCD_ILI9325_v1.3 + + DEPENDENCIES: SDCARD requires the use of SSP0. + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_SDCARD + #define CFG_SDCARD_READONLY (1) // Must be 0 or 1 + #define CFG_SDCARD_CDPORT (3) + #define CFG_SDCARD_CDPIN (0) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_SDCARD + #define CFG_SDCARD_READONLY (1) // Must be 0 or 1 + #define CFG_SDCARD_CDPORT (3) + #define CFG_SDCARD_CDPIN (0) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_SDCARD + #define CFG_SDCARD_READONLY (1) // Must be 0 or 1 + #define CFG_SDCARD_CDPORT (3) + #define CFG_SDCARD_CDPIN (0) + #endif +/*=========================================================================*/ + + +/*========================================================================= + USB + ----------------------------------------------------------------------- + + CFG_USBHID If this field is defined USB HID support will + be included. Currently uses ROM-based USB HID + CFG_USBCDC If this field is defined USB CDC support will + be included, with the USB Serial Port speed + set to 115200 BPS by default + CFG_USBCDC_BAUDRATE The default TX/RX speed. This value is used + when initialising USBCDC, and should be a + standard value like 57600, 9600, etc. + CFG_USBCDC_INITTIMEOUT The maximum delay in milliseconds to wait for + USB to connect. Must be a multiple of 10! + CFG_USBCDC_BUFFERSIZE Size of the buffer (in bytes) that stores + printf data until it can be sent out in + 64 byte frames. The buffer is required since + only one frame per ms can be sent using USB + CDC (see 'puts' in systeminit.c). + + -----------------------------------------------------------------------*/ + #define CFG_USB_VID (0x239A) + #define CFG_USB_PID (0x1002) + + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_USBHID + #define CFG_USBCDC + #define CFG_USBCDC_BAUDRATE (115200) + #define CFG_USBCDC_INITTIMEOUT (5000) + #define CFG_USBCDC_BUFFERSIZE (256) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_USBHID + #define CFG_USBCDC + #define CFG_USBCDC_BAUDRATE (115200) + #define CFG_USBCDC_INITTIMEOUT (5000) + #define CFG_USBCDC_BUFFERSIZE (256) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_USBHID + #define CFG_USBCDC + #define CFG_USBCDC_BAUDRATE (115200) + #define CFG_USBCDC_INITTIMEOUT (5000) + #define CFG_USBCDC_BUFFERSIZE (256) + #endif +/*=========================================================================*/ + + +/*========================================================================= + PRINTF REDIRECTION + ----------------------------------------------------------------------- + + CFG_PRINTF_UART Will cause all printf statements to be + redirected to UART + CFG_PRINTF_USBCDC Will cause all printf statements to be + redirect to USB Serial + CFG_PRINTF_NEWLINE This should be either "\r\n" for Windows or + "\n" for *nix + + Note: If no printf redirection definitions are present, all printf + output will be ignored, though this will also save ~350 bytes flash. + + NOTE: PRINTF Support = ~350 bytes Flash (-Os) + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_PRINTF_UART + #define CFG_PRINTF_USBCDC + #define CFG_PRINTF_NEWLINE "\r\n" + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_PRINTF_UART + #define CFG_PRINTF_USBCDC + #define CFG_PRINTF_NEWLINE "\r\n" + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_PRINTF_UART + #define CFG_PRINTF_USBCDC + #define CFG_PRINTF_NEWLINE "\r\n" + #endif +/*=========================================================================*/ + + +/*========================================================================= + COMMAND LINE INTERFACE + ----------------------------------------------------------------------- + + CFG_INTERFACE If this field is defined the UART or USBCDC + based command-line interface will be included + CFG_INTERFACE_MAXMSGSIZE The maximum number of bytes to accept for an + incoming command + CFG_INTERFACE_PROMPT The command prompt to display at the start + of every new data entry line + CFG_INTERFACE_SILENTMODE If this is set to 1 only text generated in + response to commands will be send to the + output buffer. The command prompt will not + be displayed and incoming text will not be + echoed back to the output buffer (allowing + you to see the text you have input). This + is normally only desirable in a situation + where another MCU is communicating with + the LPC1343. + CFG_INTERFACE_ENABLEIRQ If this is set to 1 the IRQ pin will be + set high when a command starts executing + and will go low when the command has + finished executing or the LCD is not busy. + This allows another device to know when a + new command can safely be sent. + CFG_INTERFACE_IRQPORT The gpio port for the IRQ/busy pin + CFG_INTERFACE_IRQPIN The gpio pin number for the IRQ/busy pin + + NOTE: The command-line interface will use either + USB-CDC or UART depending on whether + CFG_PRINTF_UART or CFG_PRINTF_USBCDC are + selected. + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_INTERFACE + #define CFG_INTERFACE_MAXMSGSIZE (256) + #define CFG_INTERFACE_PROMPT "LPC1343 >> " + #define CFG_INTERFACE_SILENTMODE (0) + #define CFG_INTERFACE_ENABLEIRQ (0) + #define CFG_INTERFACE_IRQPORT (2) + #define CFG_INTERFACE_IRQPIN (0) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_INTERFACE + #define CFG_INTERFACE_MAXMSGSIZE (256) + #define CFG_INTERFACE_PROMPT "LCD >> " + #define CFG_INTERFACE_SILENTMODE (0) + #define CFG_INTERFACE_ENABLEIRQ (1) + #define CFG_INTERFACE_IRQPORT (2) + #define CFG_INTERFACE_IRQPIN (0) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_INTERFACE + #define CFG_INTERFACE_MAXMSGSIZE (256) + #define CFG_INTERFACE_PROMPT "CMD >> " + #define CFG_INTERFACE_SILENTMODE (0) + #define CFG_INTERFACE_ENABLEIRQ (0) + #define CFG_INTERFACE_IRQPORT (2) + #define CFG_INTERFACE_IRQPIN (0) + #endif +/*=========================================================================*/ + + +/*========================================================================= + PWM SETTINGS + ----------------------------------------------------------------------- + + CFG_PWM If this is defined, a basic PWM driver + will be included using 16-bit Timer 1 and + Pin 1.9 (MAT0) for the PWM output. In + order to allow for a fixed number of + pulses to be generated, some PWM-specific + code is required in the 16-Bit Timer 1 + ISR. See "core/timer16/timer16.c" for + more information. + CFG_PWM_DEFAULT_PULSEWIDTH The default pulse width in ticks + CFG_PWM_DEFAULT_DUTYCYCLE The default duty cycle in percent + + DEPENDENCIES: PWM output requires the use of 16-bit + timer 1 and pin 1.9 (CT16B1_MAT0). + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_PWM + #define CFG_PWM_DEFAULT_PULSEWIDTH (CFG_CPU_CCLK / 1000) + #define CFG_PWM_DEFAULT_DUTYCYCLE (50) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_PWM + #define CFG_PWM_DEFAULT_PULSEWIDTH (CFG_CPU_CCLK / 1000) + #define CFG_PWM_DEFAULT_DUTYCYCLE (50) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_PWM + #define CFG_PWM_DEFAULT_PULSEWIDTH (CFG_CPU_CCLK / 1000) + #define CFG_PWM_DEFAULT_DUTYCYCLE (50) + #endif +/*=========================================================================*/ + + +/*========================================================================= + STEPPER MOTOR SETTINGS + ----------------------------------------------------------------------- + + CFG_STEPPER If this is defined, a simple bi-polar + stepper motor will be included for common + H-bridge chips like the L293D or SN754410N + + DEPENDENCIES: STEPPER requires the use of pins 3.0-3 and + 32-bit Timer 0. + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_STEPPER + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_STEPPER + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_STEPPER + #endif +/*=========================================================================*/ + + +/*========================================================================= + EEPROM + ----------------------------------------------------------------------- + + CFG_I2CEEPROM If defined, drivers for the onboard EEPROM + will be included during build + CFG_I2CEEPROM_SIZE The number of bytes available on the EEPROM + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + #define CFG_I2CEEPROM + #define CFG_I2CEEPROM_SIZE (3072) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_I2CEEPROM + #define CFG_I2CEEPROM_SIZE (3072) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_I2CEEPROM + #define CFG_I2CEEPROM_SIZE (3072) + #endif +/*=========================================================================*/ + + +/*========================================================================= + EEPROM MEMORY MAP + ----------------------------------------------------------------------- + EEPROM is used to persist certain user modifiable values to make + sure that these changes remain in effect after a reset or hard + power-down. The addresses in EEPROM for these various system + settings/values are defined below. The first 256 bytes of EEPROM + are reserved for this (0x0000..0x00FF). + + CFG_EEPROM_RESERVED The last byte of reserved EEPROM memory + + EEPROM Address (0x0000..0x00FF) + =============================== + 0 1 2 3 4 5 6 7 8 9 A B C D E F + 000x x x x x x x x x . x x . . . . . Chibi + 001x . . . . . . . . . . . . . . . . + 002x x x x x . . . . . . . . . . . . UART + 003x x x x x x x x x x x x x x x x x Touch Screen Calibration + 004x x x x x x x x x x x x x x x . . Touch Screen Calibration + 005x . . . . . . . . . . . . . . . . + 006x . . . . . . . . . . . . . . . . + 007x . . . . . . . . . . . . . . . . + 008x . . . . . . . . . . . . . . . . + 009x . . . . . . . . . . . . . . . . + 00Ax . . . . . . . . . . . . . . . . + 00Bx . . . . . . . . . . . . . . . . + 00Cx . . . . . . . . . . . . . . . . + 00Dx . . . . . . . . . . . . . . . . + 00Ex . . . . . . . . . . . . . . . . + 00Fx . . . . . . . . . . . . . . . . + + -----------------------------------------------------------------------*/ + #define CFG_EEPROM_RESERVED (0x00FF) // Protect first 256 bytes of memory + #define CFG_EEPROM_CHIBI_IEEEADDR (uint16_t)(0x0000) // 8 + #define CFG_EEPROM_CHIBI_SHORTADDR (uint16_t)(0x0009) // 2 + #define CFG_EEPROM_TOUCHSCREEN_CALIBRATED (uint16_t)(0x0030) // 1 + #define CFG_EEPROM_TOUCHSCREEN_CAL_AN (uint16_t)(0x0031) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_BN (uint16_t)(0x0035) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_CN (uint16_t)(0x0039) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_DN (uint16_t)(0x003D) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_EN (uint16_t)(0x0041) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_FN (uint16_t)(0x0045) // 4 + #define CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER (uint16_t)(0x0049) // 4 + #define CFG_EEPROM_TOUCHSCREEN_THRESHHOLD (uint16_t)(0x004D) // 1 + #define CFG_EEPROM_UART_SPEED (uint16_t)(0x0020) // 4 +/*=========================================================================*/ + + +/*========================================================================= + LM75B TEMPERATURE SENSOR + ----------------------------------------------------------------------- + + CFG_LM75B If defined, drivers for an optional LM75B + temperature sensor will be included during + build (requires external HW) + + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_LM75B + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_LM75B + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_LM75B + #endif +/*=========================================================================*/ + + +/*========================================================================= + CHIBI WIRELESS STACK + ----------------------------------------------------------------------- + + CFG_CHIBI If defined, the CHIBI wireless stack will be + included during build. Requires external HW. + CFG_CHIBI_MODE The mode to use when receiving and transmitting + wireless data. See chb_drvr.h for possible values + CFG_CHIBI_POWER The power level to use when transmitting. See + chb_drvr.h for possible values + CFG_CHIBI_CHANNEL 802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz) + CFG_CHIBI_PANID 16-bit PAN Identifier (ex.0x1234) + CFG_CHIBI_PROMISCUOUS Set to 1 to enabled promiscuous mode or + 0 to disable it. If promiscuous mode is + enabled be sure to set CFG_CHIBI_BUFFERSIZE + to an appropriately large value (ex. 1024) + CFG_CHIBI_BUFFERSIZE The size of the message buffer in bytes + + DEPENDENCIES: Chibi requires the use of SSP0, 16-bit timer + 0 and pins 3.1, 3.2, 3.3. It also requires + the presence of CFG_I2CEEPROM. + + NOTE: These settings are not relevant to all boards! + 'tools/schematics/AT86RF212LPC1114_v1.6.pdf' + show how 'CHIBI' is meant to be connected + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_CHIBI + #define CFG_CHIBI_MODE (0) // OQPSK_868MHZ + #define CFG_CHIBI_POWER (0xE9) // CHB_PWR_EU2_3DBM + #define CFG_CHIBI_CHANNEL (0) // 868-868.6 MHz + #define CFG_CHIBI_PANID (0x1234) + #define CFG_CHIBI_PROMISCUOUS (0) + #define CFG_CHIBI_BUFFERSIZE (128) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_CHIBI + #define CFG_CHIBI_MODE (0) // OQPSK_868MHZ + #define CFG_CHIBI_POWER (0xE9) // CHB_PWR_EU2_3DBM + #define CFG_CHIBI_CHANNEL (0) // 868-868.6 MHz + #define CFG_CHIBI_PANID (0x1234) + #define CFG_CHIBI_PROMISCUOUS (0) + #define CFG_CHIBI_BUFFERSIZE (128) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + #define CFG_CHIBI + #define CFG_CHIBI_MODE (0) // OQPSK_868MHZ + #define CFG_CHIBI_POWER (0xE9) // CHB_PWR_EU2_3DBM + #define CFG_CHIBI_CHANNEL (0) // 868-868.6 MHz + #define CFG_CHIBI_PANID (0x1234) + #define CFG_CHIBI_PROMISCUOUS (0) + #define CFG_CHIBI_BUFFERSIZE (1024) + #endif +/*=========================================================================*/ + + +/*========================================================================= + TFT LCD + ----------------------------------------------------------------------- + + CFG_TFTLCD If defined, this will cause drivers for + a pre-determined LCD screen to be included + during build. Only one LCD driver can be + included during the build process (for ex. + 'drivers/lcd/hw/ILI9325.c') + CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be + included for 3x6, 5x8, 7x8 and 8x8 fonts. + This should only be enabled if these small + fonts are required since there is already + support for larger fonts generated with + Dot Factory + http://www.pavius.net/downloads/tools/53-the-dot-factory + CFG_TFTLCD_TS_DEFAULTTHRESHOLD Default minimum threshold to trigger a + touch event with the touch screen (and exit + from 'tsWaitForEvent' in touchscreen.c). + Should be an 8-bit value somewhere between + 8 and 75 in normal circumstances. This is + the default value and may be overriden by + a value stored in EEPROM. + CFG_TFTLCD_TS_KEYPADDELAY The delay in milliseconds between key + presses in dialogue boxes + + PIN LAYOUT: The pin layout that is used by this driver + can be seen in the following schematic: + /tools/schematics/Breakout_TFTLCD_ILI9325_v1.3 + + DEPENDENCIES: TFTLCD requires the use of pins 1.8, 1.9, + 1.10, 1.11, 3.3 and 2.1-9. + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_TFTLCD + #define CFG_TFTLCD_INCLUDESMALLFONTS (0) + #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50) + #define CFG_TFTLCD_TS_KEYPADDELAY (100) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + #define CFG_TFTLCD + #define CFG_TFTLCD_INCLUDESMALLFONTS (0) + #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50) + #define CFG_TFTLCD_TS_KEYPADDELAY (100) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_TFTLCD + #define CFG_TFTLCD_INCLUDESMALLFONTS (0) + #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50) + #define CFG_TFTLCD_TS_KEYPADDELAY (100) + #endif +/*=========================================================================*/ + + +/*========================================================================= + 128x64 Graphic LCDs + ----------------------------------------------------------------------- + + CFG_ST7565 If defined, this will cause drivers for + the 128x64 pixel ST7565 LCD to be included + CFG_SSD1306 If defined, this will cause drivers for + the 128x64 pixel SSD1306 OLED display to be + included + + Note: LPC1114 @ 36MHz and the ST7565 with the + backlight enabled consumes ~35mA + + DEPENDENCIES: ST7565 requires the use of pins 2.1-6. + DEPENDENCIES: SSD1306 requires the use of pins 2.1-6. + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_ST7565 + // #define CFG_SSD1306 + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_ST7565 + // #define CFG_SSD1306 + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_ST7565 + // #define CFG_SSD1306 + #endif +/*=========================================================================*/ + + +/*========================================================================= + RSA Encryption + ----------------------------------------------------------------------- + + CFG_RSA If defined, support for basic RSA + encryption will be included. + CFG_RSA_BITS Indicates the number of bits used for + RSA encryption keys. To keep code size + reasonable, RSA encryption is currently + limited to using 64-bit or 32-bit numbers, + with 64-bit providing higher security, and + 32-bit providing smaller encrypted text + size. + + NOTE: Please note that Printf can not be + used to display 64-bit values (%lld)! + -----------------------------------------------------------------------*/ + #ifdef CFG_BRD_LPC1343_REFDESIGN + // #define CFG_RSA + #define CFG_RSA_BITS (32) + #endif + + #ifdef CFG_BRD_LPC1343_TFTLCDSTANDALONE + // #define CFG_RSA + #define CFG_RSA_BITS (32) + #endif + + #ifdef CFG_BRD_LPC1343_802154USBSTICK + // #define CFG_RSA + #define CFG_RSA_BITS (32) + #endif +/*=========================================================================*/ + + + + +/*========================================================================= + CONFIG FILE VALIDATION + ------------------------------------------------------------------------- + Basic error checking to make sure that incompatible defines are not + enabled at the same time, etc. + + =========================================================================*/ + +#if !defined CFG_BRD_LPC1343_REFDESIGN && !defined CFG_BRD_LPC1343_TFTLCDSTANDALONE && !defined CFG_BRD_LPC1343_802154USBSTICK + #error "You must defined a target board (CFG_BRD_LPC1343_REFDESIGN or CFG_BRD_LPC1343_TFTLCDSTANDALONE or CFG_BRD_LPC1343_802154USBSTICK)" +#endif +#if (defined CFG_BRD_LPC1343_REFDESIGN && defined CFG_BRD_LPC1343_TFTLCDSTANDALONE) || (defined CFG_BRD_LPC1343_TFTLCDSTANDALONE && defined CFG_BRD_LPC1343_802154USBSTICK) || (defined CFG_BRD_LPC1343_REFDESIGN && defined CFG_BRD_LPC1343_802154USBSTICK) + #error "Only one target board can be defined at a time" +#endif + +#if defined CFG_PRINTF_USBCDC && defined CFG_PRINTF_UART + #error "CFG_PRINTF_UART or CFG_PRINTF_USBCDC cannot both be defined at once" +#endif + +#if defined CFG_PRINTF_USBCDC && !defined CFG_USBCDC + #error "CFG_PRINTF_CDC requires CFG_USBCDC to be defined as well" +#endif + +#if defined CFG_USBCDC && defined CFG_USBHID + #error "Only one USB class can be defined at a time (CFG_USBCDC or CFG_USBHID)" +#endif + +#if defined CFG_SSP0_SCKPIN_2_11 && defined CFG_SSP0_SCKPIN_0_6 + #error "Only one SCK pin can be defined at a time for SSP0" +#endif + +#if !defined CFG_SSP0_SCKPIN_2_11 && !defined CFG_SSP0_SCKPIN_0_6 + #error "An SCK pin must be selected for SSP0 (CFG_SSP0_SCKPIN_2_11 or CFG_SSP0_SCKPIN_0_6)" +#endif + +#ifdef CFG_INTERFACE + #if !defined CFG_PRINTF_UART && !defined CFG_PRINTF_USBCDC + #error "CFG_PRINTF_UART or CFG_PRINTF_USBCDC must be defined for for CFG_INTERFACE Input/Output" + #endif + #if defined CFG_PRINTF_USBCDC && CFG_INTERFACE_SILENTMODE == 1 + #error "CFG_INTERFACE_SILENTMODE typically isn't enabled with CFG_PRINTF_USBCDC" + #endif +#endif + +#ifdef CFG_CHIBI + #if !defined CFG_I2CEEPROM + #error "CFG_CHIBI requires CFG_I2CEEPROM to store and retrieve addresses" + #endif + #ifdef CFG_SDCARD + #error "CFG_CHIBI and CFG_SDCARD can not be defined at the same time. Only one SPI block is available on the LPC1343." + #endif + #ifdef CFG_TFTLCD + #error "CFG_CHIBI and CFG_TFTLCD can not be defined at the same time since they both use pins 1.8, 1.9 and 1.10." + #endif + #ifdef CFG_PWM + #error "CFG_CHIBI and CFG_PWM can not be defined at the same time since they both use pin 1.9." + #endif + #if CFG_CHIBI_PROMISCUOUS != 0 && CFG_CHIBI_PROMISCUOUS != 1 + #error "CFG_CHIBI_PROMISCUOUS must be equal to either 1 or 0" + #endif +#endif + +#ifdef CFG_TFTLCD + #ifdef CFG_ST7565 + #error "CFG_TFTLCD and CFG_ST7565 can not be defined at the same time." + #endif + #ifdef CFG_SSD1306 + #error "CFG_TFTLCD and CFG_SSD1306 can not be defined at the same time." + #endif + #ifdef CFG_PWM + #error "CFG_TFTLCD and CFG_PWM can not be defined at the same time since they both use pin 1.9." + #endif + #if !defined CFG_I2CEEPROM + #error "CFG_TFTLCD requires CFG_I2CEEPROM to store and retrieve configuration settings" + #endif +#endif + +#ifdef CFG_SDCARD + #ifdef CFG_STEPPER + #error "CFG_SDCARD and CFG_STEPPER can not be defined at the same time since they both use pin 3.0." + #endif +#endif + +#ifdef CFG_ST7565 + #ifdef CFG_SSD1306 + #error "CFG_ST7565 and CFG_SSD1306 can not be defined at the same time" + #endif +#endif + +#ifdef CFG_RSA + #if CFG_RSA_BITS != 64 && CFG_RSA_BITS != 32 + #error "CFG_RSA_BITS must be equal to either 32 or 64." + #endif +#endif + +#endif diff --git a/sysdefs.h b/sysdefs.h new file mode 100644 index 0000000..bf79c8e --- /dev/null +++ b/sysdefs.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/*! + @file sysdefs.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _SYSDEFS_H_ +#define _SYSDEFS_H_ + +#include +#include +#include + +// Stay compatible with ugly "windows" style +#define BOOL bool +#define TRUE true +#define FALSE false + +typedef volatile uint8_t REG8; +typedef volatile uint16_t REG16; +typedef volatile uint32_t REG32; +typedef unsigned char byte_t; + +#define pREG8 (REG8 *) +#define pREG16 (REG16 *) +#define pREG32 (REG32 *) + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#endif + diff --git a/sysinit.c b/sysinit.c new file mode 100644 index 0000000..60b4d3b --- /dev/null +++ b/sysinit.c @@ -0,0 +1,278 @@ +/**************************************************************************/ +/*! + @file sysinit.c + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include +#include +#include + +#include "sysinit.h" + +#include "core/cpu/cpu.h" +#include "core/pmu/pmu.h" +#include "core/adc/adc.h" + +#ifdef CFG_PRINTF_UART + #include "core/uart/uart.h" +#endif + +#ifdef CFG_INTERFACE + #include "core/cmd/cmd.h" +#endif + +#ifdef CFG_CHIBI + #include "drivers/chibi/chb.h" +#endif + +#ifdef CFG_USBHID + #include "core/usbhid-rom/usbhid.h" +#endif + +#ifdef CFG_USBCDC + volatile unsigned int lastTick; + #include "core/usbcdc/usb.h" + #include "core/usbcdc/usbcore.h" + #include "core/usbcdc/usbhw.h" + #include "core/usbcdc/cdcuser.h" + #include "core/usbcdc/cdc_buf.h" +#endif + +#ifdef CFG_ST7565 + #include "drivers/lcd/bitmap/st7565/st7565.h" + #include "drivers/lcd/smallfonts.h" +#endif + +#ifdef CFG_SSD1306 + #include "drivers/lcd/bitmap/ssd1306/ssd1306.h" + #include "drivers/lcd/smallfonts.h" +#endif + +#ifdef CFG_TFTLCD + #include "drivers/lcd/tft/lcd.h" + #include "drivers/lcd/tft/touchscreen.h" + #include "drivers/lcd/tft/drawing.h" +#endif + +#ifdef CFG_I2CEEPROM + #include "drivers/eeprom/mcp24aa/mcp24aa.h" + #include "drivers/eeprom/eeprom.h" +#endif + +#ifdef CFG_PWM + #include "core/pwm/pwm.h" +#endif + +#ifdef CFG_SDCARD + #include "core/ssp/ssp.h" + #include "drivers/fatfs/diskio.h" + #include "drivers/fatfs/ff.h" + + DWORD get_fattime () + { + // ToDo! + return 0; + } +#endif + +/**************************************************************************/ +/*! + Configures the core system clock and sets up any mandatory + peripherals like the systick timer, UART for printf, etc. + + This function should set the HW to the default state you wish to be + in coming out of reset/startup, such as disabling or enabling LEDs, + setting specific pin states, etc. +*/ +/**************************************************************************/ +void systemInit() +{ + cpuInit(); // Configure the CPU + systickInit(CFG_SYSTICK_DELAY_IN_MS); // Start systick timer + gpioInit(); // Enable GPIO + pmuInit(); // Configure power management + adcInit(); // Config adc pins to save power + + // Set LED pin as output and turn LED off + gpioSetDir(CFG_LED_PORT, CFG_LED_PIN, 1); + gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + + // Initialise EEPROM + #ifdef CFG_I2CEEPROM + mcp24aaInit(); + #endif + + // Initialise UART with the default baud rate + #ifdef CFG_PRINTF_UART + uint32_t uart = eepromReadU32(CFG_EEPROM_UART_SPEED); + if ((uart == 0xFFFFFFFF) || (uart > 115200)) + { + uartInit(CFG_UART_BAUDRATE); // Use default baud rate + } + else + { + uartInit(uart); // Use baud rate from EEPROM + } + #endif + + // Initialise PWM (requires 16-bit Timer 1 and P1.9) + #ifdef CFG_PWM + pwmInit(); + #endif + + // Initialise USB HID + #ifdef CFG_USBHID + usbHIDInit(); + #endif + + // Initialise USB CDC + #ifdef CFG_USBCDC + lastTick = systickGetTicks(); // Used to control output/printf timing + CDC_Init(); // Initialise VCOM + USB_Init(); // USB Initialization + USB_Connect(TRUE); // USB Connect + // Wait until USB is configured or timeout occurs + uint32_t usbTimeout = 0; + while ( usbTimeout < CFG_USBCDC_INITTIMEOUT / 10 ) + { + if (USB_Configuration) break; + systickDelay(10); // Wait 10ms + usbTimeout++; + } + #endif + + // Printf can now be used with UART or USBCDC + + // Initialise the ST7565 128x64 pixel display + #ifdef CFG_ST7565 + st7565Init(); + st7565ClearScreen(); // Clear the screen + st7565Backlight(1); // Enable the backlight + #endif + + // Initialise the SSD1306 OLED display + #ifdef CFG_SSD1306 + ssd1306Init(SSD1306_SWITCHCAPVCC); + ssd1306ClearScreen(); // Clear the screen + #endif + + // Initialise TFT LCD Display + #ifdef CFG_TFTLCD + lcdInit(); + #endif + + // Initialise Chibi + // Warning: CFG_CHIBI must be disabled if no antenna is connected, + // otherwise the SW will halt during initialisation + #ifdef CFG_CHIBI + // Write addresses to EEPROM for the first time if necessary + // uint16_t addr_short = 0x0025; + // uint64_t addr_ieee = 0x0000000000000025; + // mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t *)&addr_short, 2); + // mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t *)&addr_ieee, 8); + chb_init(); + // chb_pcb_t *pcb = chb_get_pcb(); + // printf("%-40s : 0x%04X%s", "Chibi Initialised", pcb->src_addr, CFG_PRINTF_NEWLINE); + #endif + + // Start the command line interface + #ifdef CFG_INTERFACE + cmdInit(); + #endif +} + +/**************************************************************************/ +/*! + @brief Sends a single byte to a pre-determined peripheral (UART, etc.). + + @param[in] byte + Byte value to send +*/ +/**************************************************************************/ +void __putchar(const char c) +{ + #ifdef CFG_PRINTF_UART + // Send output to UART + uartSendByte(c); + #endif +} + +/**************************************************************************/ +/*! + @brief Sends a string to a pre-determined end point (UART, etc.). + + @param[in] str + Text to send + + @note This function is only called when using the GCC-compiler + in Codelite or running the Makefile manually. This function + will not be called when using the C library in Crossworks for + ARM. +*/ +/**************************************************************************/ +int puts(const char * str) +{ + // There must be at least 1ms between USB frames (of up to 64 bytes) + // This buffers all data and writes it out from the buffer one frame + // and one millisecond at a time + #ifdef CFG_PRINTF_USBCDC + if (USB_Configuration) + { + while(*str) + cdcBufferWrite(*str++); + // Check if we can flush the buffer now or if we need to wait + unsigned int currentTick = systickGetTicks(); + if (currentTick != lastTick) + { + uint8_t frame[64]; + uint32_t bytesRead = 0; + while (cdcBufferDataPending()) + { + // Read up to 64 bytes as long as possible + bytesRead = cdcBufferReadLen(frame, 64); + USB_WriteEP (CDC_DEP_IN, frame, bytesRead); + systickDelay(1); + } + lastTick = currentTick; + } + } + #else + // Handle output character by character in __putchar + while(*str) __putchar(*str++); + #endif + + return 0; +} diff --git a/sysinit.h b/sysinit.h new file mode 100644 index 0000000..f7beabd --- /dev/null +++ b/sysinit.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file sysinit.h + @author K. Townsend (microBuilder.eu) + @date 22 March 2010 + @version 0.10 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef __SYSINIT_H__ +#define __SYSINIT_H__ + +#include "projectconfig.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +// Function prototypes +void systemInit(); + +#endif \ No newline at end of file diff --git a/tools/colors_h.png b/tools/colors_h.png new file mode 100644 index 0000000..4212ae6 Binary files /dev/null and b/tools/colors_h.png differ diff --git a/tools/dotfactory/DotFactorySettings.png b/tools/dotfactory/DotFactorySettings.png new file mode 100644 index 0000000..f0d87c5 Binary files /dev/null and b/tools/dotfactory/DotFactorySettings.png differ diff --git a/tools/dotfactory/DotFactorySettings_FixedWidth.png b/tools/dotfactory/DotFactorySettings_FixedWidth.png new file mode 100644 index 0000000..8bd97de Binary files /dev/null and b/tools/dotfactory/DotFactorySettings_FixedWidth.png differ diff --git a/tools/dotfactory/OutputConfigs.xml b/tools/dotfactory/OutputConfigs.xml new file mode 100644 index 0000000..b0b92a9 --- /dev/null +++ b/tools/dotfactory/OutputConfigs.xml @@ -0,0 +1,49 @@ + + + + true + true + true + C + # + RotateNinety + false + false + Fixed + Tighest + AtColumn + MsbFirst + Hex + 0x + true + DisplayInBits + DontDisplay + DisplayInBytes + true + 5 + VariableWidth + + + true + true + true + C + # + RotateNinety + false + false + Fixed + Fixed + AtColumn + MsbFirst + Hex + 0x + true + DisplayInBits + DontDisplay + DisplayInBytes + true + 8 + FixedWidth + + \ No newline at end of file diff --git a/tools/dotfactory/TheDotFactory-src-0.0.9.7z b/tools/dotfactory/TheDotFactory-src-0.0.9.7z new file mode 100644 index 0000000..f2ee5a9 Binary files /dev/null and b/tools/dotfactory/TheDotFactory-src-0.0.9.7z differ diff --git a/tools/dotfactory/TheDotFactory.exe b/tools/dotfactory/TheDotFactory.exe new file mode 100644 index 0000000..eeec52d Binary files /dev/null and b/tools/dotfactory/TheDotFactory.exe differ diff --git a/tools/dotfactory/readme.txt b/tools/dotfactory/readme.txt new file mode 100644 index 0000000..b7891ae --- /dev/null +++ b/tools/dotfactory/readme.txt @@ -0,0 +1,14 @@ +The Dot Factory is a GPL license program that can be used to +convert TTF fonts for .c files. The latest Windows binary +and source files can be found at: + +http://www.pavius.net/downloads/tools/53-the-dot-factory + +The source and binary files are included here purely for +convenience sake. + +The following fonts are used in the LPC1343 +Code Base: + +DejaVu - http://dejavu-fonts.org/wiki/Main_Page +Bitsream Vera - http://www.gnome.org/fonts/ \ No newline at end of file diff --git a/tools/examples/basics/blinky/main.c b/tools/examples/basics/blinky/main.c new file mode 100644 index 0000000..7a6484d --- /dev/null +++ b/tools/examples/basics/blinky/main.c @@ -0,0 +1,72 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +/**************************************************************************/ +/*! + Cause the LED to blink once per second using a blocking delay +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + while (1) + { + // Wait one second + systickDelay(1000); + // Toggle the LED + if (gpioGetValue(CFG_LED_PORT, CFG_LED_PIN) == CFG_LED_OFF) + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + } + else + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + } + } + + return 0; +} diff --git a/tools/examples/basics/blinky/readme.txt b/tools/examples/basics/blinky/readme.txt new file mode 100644 index 0000000..84b078f --- /dev/null +++ b/tools/examples/basics/blinky/readme.txt @@ -0,0 +1 @@ +Causes the LED to blink once per second \ No newline at end of file diff --git a/tools/examples/basics/blinky_nonblocking/main.c b/tools/examples/basics/blinky_nonblocking/main.c new file mode 100644 index 0000000..0de837d --- /dev/null +++ b/tools/examples/basics/blinky_nonblocking/main.c @@ -0,0 +1,94 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +#ifdef CFG_INTERFACE + #include "core/cmd/cmd.h" +#endif + +/**************************************************************************/ +/*! + Causes the LED to flash every second using a non-blocking delay, + and constantly checks if any incoming characters have arrived in + the UART buffer for the CLI + + projectconfig.h settings: + -------------------------------------------------- + CFG_INTERFACE -> Enabled + CFG_PRINTF_USBCDC -> Enabled if USB is used for the CLI + CFG_PRINTF_UART -> Enabled if UART is used for the CLI +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + uint32_t currentSecond, lastSecond; + currentSecond = lastSecond = 0; + + // Toggle LED once per second and constantly check CLI input + while (1) + { + // Get the number of seconds the CPU has been active + // If the value has changed we've advanced at least 1 second + currentSecond = systickGetSecondsActive(); + if (currentSecond != lastSecond) + { + lastSecond = currentSecond; + // Toggle the LED + if (gpioGetValue(CFG_LED_PORT, CFG_LED_PIN) == CFG_LED_OFF) + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + } + else + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + } + } + + // Poll for CLI input if CFG_INTERFACE is enabled in projectconfig.h + #ifdef CFG_INTERFACE + cmdPoll(); + #endif + } + + return 0; +} diff --git a/tools/examples/basics/blinky_nonblocking/readme.txt b/tools/examples/basics/blinky_nonblocking/readme.txt new file mode 100644 index 0000000..18a74d8 --- /dev/null +++ b/tools/examples/basics/blinky_nonblocking/readme.txt @@ -0,0 +1,5 @@ +Causes the LED to blink once per second using a non-blocking delay, as well +as constantly checking the UART or USB CDC buffer for incoming data to be +passed to the CLI. You can connect to the CLI using UART or USB, send and +receive commands, and the LED should continue blinking (as long as a command +is not using the MCU). \ No newline at end of file diff --git a/tools/examples/basics/pwm_piezobuzzer/main.c b/tools/examples/basics/pwm_piezobuzzer/main.c new file mode 100644 index 0000000..d65ad07 --- /dev/null +++ b/tools/examples/basics/pwm_piezobuzzer/main.c @@ -0,0 +1,110 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +#ifdef CFG_INTERFACE + #include "core/cmd/cmd.h" +#endif + +#ifdef CFG_PWM + #include "core/pwm/pwm.h" +#endif + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + #ifndef CFG_PWM + #ERROR "CFG_PWM must be enabled in projectconfig.h for this example." + #endif + + // Configure cpu and mandatory peripherals + // PWM is initialised in systemInit and defaults to using P1.9 + systemInit(); + + // Set duty cycle to 50% for square wave output + pwmSetDutyCycle(50); + + // Frequency can be set anywhere from 2khz and 10khz (4khz is loudest) + // Note: Since this is a 16-bit timer, make sure the delay is not + // greater than 0xFFFF (65535), though anything 2khz and higher + // is within an acceptable range + // The piezo buzzer used for this example is the PS1240, available at + // http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=160 + pwmSetFrequencyInTicks(CFG_CPU_CCLK / 2000); + + uint32_t currentSecond, lastSecond; + currentSecond = lastSecond = 0; + + while (1) + { + // Beep the piezo buzzer very briefly once per second, toggling the LED at the same time + currentSecond = systickGetSecondsActive(); + // Make sure that at least one second has passed + if (currentSecond != lastSecond) + { + // Update the second tracker + lastSecond = currentSecond; + // Set the LED state and buzzer loudness depending on the current LED state + if (gpioGetValue(CFG_LED_PORT, CFG_LED_PIN) == CFG_LED_OFF) + { + pwmSetFrequencyInTicks(CFG_CPU_CCLK / 4000); // 4khz (louder) + pwmStartFixed(200); // 2x as long as @ 2khz since it's 2x faster + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); // Turn the LED on + } + else + { + pwmSetFrequencyInTicks(CFG_CPU_CCLK / 2000); // 2khz (softer) + pwmStartFixed(100); + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); // Turn the LED off + } + } + } + + return 0; +} diff --git a/tools/examples/basics/pwm_piezobuzzer/readme.txt b/tools/examples/basics/pwm_piezobuzzer/readme.txt new file mode 100644 index 0000000..3a39b81 --- /dev/null +++ b/tools/examples/basics/pwm_piezobuzzer/readme.txt @@ -0,0 +1,12 @@ +This example uses a 16-bit timer for PWM, and makes a common +piezo buzzer beep briefly once per second at an alternating +frequency. + +The piezo-buzzer used in this example is the PS1240, available +from Adafruit Industries at: + +http://www.adafruit.com/index.php?main_page=product_info&cPath=35&products_id=160 + +The buzzer should have one pin (either is fine) connected to P1.9 +on the LPC1343, and the other pin connected to GND. CFG_PWM must also +be enabled in projectconfig.h. \ No newline at end of file diff --git a/tools/examples/chibi/receive/main.c b/tools/examples/chibi/receive/main.c new file mode 100644 index 0000000..3daafcf --- /dev/null +++ b/tools/examples/chibi/receive/main.c @@ -0,0 +1,117 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "drivers/chibi/chb.h" +#include "drivers/chibi/chb_drvr.h" + +static chb_rx_data_t rx_data; + +/**************************************************************************/ +/*! + Converts the ED (Energy Detection) value to dBm using the following + formula: dBm = RSSI_BASE_VAL + 1.03 * ED + + For more information see section 6.5 of the AT86RF212 datasheet +*/ +/**************************************************************************/ +int edToDBM(uint32_t ed) +{ + #if CFG_CHIBI_MODE == 0 || CFG_CHIBI_MODE == 1 || CFG_CHIBI_MODE == 2 + // Calculate for OQPSK (RSSI Base Value = -100) + int dbm = (103 * ed - 10000); + #else + // Calculate for BPSK (RSSI Base Value = -98) + int dbm = (103 * ed - 9800); + #endif + + return dbm / 100; +} + +/**************************************************************************/ +/*! + Constantly checks for incoming messages, and displays them using + printf when they arrive. This program will display messages sent + to the global broadcast address (0xFFFF) or messages addressed to + this node using it's unique 16-bit ID. + + projectconfig.h settings: + -------------------------------------------------- + CFG_CHIBI -> Enabled + CFG_CHIBI_PROMISCUOUS -> 0 + CFG_CHIBI_BUFFERSIZE -> 128 +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + // Make sure that projectconfig.h is properly configured for this example + #if !defined CFG_CHIBI + #error "CFG_CHIBI must be enabled in projectconfig.h for this example" + #endif + #if CFG_CHIBI_PROMISCUOUS != 0 + #error "CFG_CHIBI_PROMISCUOUS must be set to 0 in projectconfig.h for this example" + #endif + + // Get a reference to the Chibi peripheral control block + chb_pcb_t *pcb = chb_get_pcb(); + + while(1) + { + // Check for incoming messages + while (pcb->data_rcv) + { + // Enable LED to indicate message reception + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + // get the length of the data + rx_data.len = chb_read(&rx_data); + // make sure the length is nonzero + if (rx_data.len) + { + int dbm = edToDBM(pcb->ed); + printf("Message received from node %02X: %s, len=%d, dBm=%d.%s", rx_data.src_addr, rx_data.data, rx_data.len, dbm, CFG_PRINTF_NEWLINE); + } + // Disable LED + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + } + } + + return 0; +} diff --git a/tools/examples/chibi/receive/readme.txt b/tools/examples/chibi/receive/readme.txt new file mode 100644 index 0000000..d0afae6 --- /dev/null +++ b/tools/examples/chibi/receive/readme.txt @@ -0,0 +1,3 @@ +Looks for any incoming messages using the global broadcast address +(0xFFFF) of this node's addresses and displays the message content +using printf (redirect to UART by default). \ No newline at end of file diff --git a/tools/examples/chibi/sniffer_wsbridge/main.c b/tools/examples/chibi/sniffer_wsbridge/main.c new file mode 100644 index 0000000..0e3bcdc --- /dev/null +++ b/tools/examples/chibi/sniffer_wsbridge/main.c @@ -0,0 +1,146 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" + +#if defined CFG_CHIBI + #include + #include + #include "drivers/chibi/chb.h" + #include "drivers/chibi/chb_drvr.h" + #include "core/uart/uart.h" + static chb_rx_data_t rx_data; +#endif + +#ifdef CFG_PRINTF_USBCDC + volatile unsigned int lastTick; + #include "core/usbcdc/usb.h" + #include "core/usbcdc/usbcore.h" + #include "core/usbcdc/usbhw.h" + #include "core/usbcdc/cdcuser.h" + #include "core/usbcdc/cdc_buf.h" +#endif + +/**************************************************************************/ +/*! + Use Chibi as a wireless sniffer and write all captured frames + to UART or USB CDC for wsbridge to handle (see "tools/wsbridge") + + projectconfig.h settings: + -------------------------------------------------- + CFG_CHIBI -> Enabled + CFG_CHIBI_PROMISCUOUS -> 1 + CFG_CHIBI_BUFFERSIZE -> 1024 +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + // Check if projectconfig.h is properly configured for this example + #if !defined CFG_CHIBI + #error "CFG_CHIBI must be enabled in projectconfig.h for this example" + #endif + #if CFG_CHIBI_PROMISCUOUS == 0 + #error "CFG_CHIBI_PROMISCUOUS must set to 1 in projectconfig.h for this example" + #endif + #if defined CFG_INTERFACE + #error "CFG_INTERFACE must be disabled in projectconfig.h for this example" + #endif + + #if defined CFG_CHIBI && CFG_CHIBI_PROMISCUOUS != 0 + // Get a reference to the Chibi peripheral control block + chb_pcb_t *pcb = chb_get_pcb(); + + // Wait for incoming frames and transmit the raw data over uart + while(1) + { + // Check for incoming messages + while (pcb->data_rcv) + { + // get the length of the data + rx_data.len = chb_read(&rx_data); + // make sure the length is nonzero + if (rx_data.len) + { + // Enable LED to indicate message reception + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + + + // Send raw data the to PC for processing using wsbridge + uint8_t i; + for (i=0; i + #include + #include "drivers/chibi/chb.h" + #include "drivers/chibi/chb_drvr.h" +#endif + +/**************************************************************************/ +/*! + Broadcast a basic message every 250 milliseconds + + projectconfig.h settings: + -------------------------------------------------- + CFG_CHIBI -> Enabled + CFG_CHIBI_PROMISCUOUS -> 0 + CFG_CHIBI_BUFFERSIZE -> 128 +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + // Make sure that projectconfig.h is properly configured for this example + #if !defined CFG_CHIBI + #error "CFG_CHIBI must be enabled in projectconfig.h for this example" + #endif + #if CFG_CHIBI_PROMISCUOUS != 0 + #error "CFG_CHIBI_PROMISCUOUS must be set to 0 in projectconfig.h for this example" + #endif + + #ifdef CFG_CHIBI + uint32_t counter = 0; + chb_pcb_t *pcb = chb_get_pcb(); + + while(1) + { + // Enable LED + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + // Create and send the message + char text[10]; + counter++; + itoa(counter, text, 10); + chb_write(0xFFFF, text, strlen(text) + 1); + // Disable LED + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + systickDelay(250); + } + #endif + + return 0; +} diff --git a/tools/examples/chibi/transmit/readme.txt b/tools/examples/chibi/transmit/readme.txt new file mode 100644 index 0000000..66c2496 --- /dev/null +++ b/tools/examples/chibi/transmit/readme.txt @@ -0,0 +1,2 @@ +Broadcasts a basic messages every 250 milliseconds that will be +received by every node within hearing distance. \ No newline at end of file diff --git a/tools/examples/default/main.c b/tools/examples/default/main.c new file mode 100644 index 0000000..8b75435 --- /dev/null +++ b/tools/examples/default/main.c @@ -0,0 +1,110 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +#ifdef CFG_INTERFACE + #include "core/cmd/cmd.h" +#endif + +/**************************************************************************/ +/*! + Approximates a 1 millisecond delay using "nop". This is less + accurate than a dedicated timer, but is useful in certain situations. + + The number of ticks to delay depends on the optimisation level set + when compiling (-O). Depending on the compiler settings, one of the + two defined values for 'delay' should be used. +*/ +/**************************************************************************/ +void delayms(uint32_t ms) +{ + uint32_t delay = ms * ((CFG_CPU_CCLK / 100) / 45); // Release Mode (-Os) + // uint32_t delay = ms * ((CFG_CPU_CCLK / 100) / 120); // Debug Mode (No optimisations) + + while (delay > 0) + { + __asm volatile ("nop"); + delay--; + } +} + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + uint32_t currentSecond, lastSecond; + currentSecond = lastSecond = 0; + + while (1) + { + // Toggle LED once per second ... rollover = 136 years :) + currentSecond = systickGetSecondsActive(); + if (currentSecond != lastSecond) + { + lastSecond = currentSecond; + if (gpioGetValue(CFG_LED_PORT, CFG_LED_PIN) == CFG_LED_OFF) + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + } + else + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + } + } + + // Poll for CLI input if CFG_INTERFACE is enabled in projectconfig.h + #ifdef CFG_INTERFACE + cmdPoll(); + #endif + } + + return 0; +} diff --git a/tools/examples/default/readme.txt b/tools/examples/default/readme.txt new file mode 100644 index 0000000..dd4bb08 --- /dev/null +++ b/tools/examples/default/readme.txt @@ -0,0 +1,3 @@ +This is the default main.c file used in the code base and will cause +the test LED to blinks once per second and process any incoming data +for the CLI if CFG_INTERFACE is enabled in projectconfig.h \ No newline at end of file diff --git a/tools/examples/lcd/tft/basic_ui/basic_ui_screenshot.png b/tools/examples/lcd/tft/basic_ui/basic_ui_screenshot.png new file mode 100644 index 0000000..36f52c8 Binary files /dev/null and b/tools/examples/lcd/tft/basic_ui/basic_ui_screenshot.png differ diff --git a/tools/examples/lcd/tft/basic_ui/main.c b/tools/examples/lcd/tft/basic_ui/main.c new file mode 100644 index 0000000..9570765 --- /dev/null +++ b/tools/examples/lcd/tft/basic_ui/main.c @@ -0,0 +1,215 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/adc/adc.h" +#include "core/systick/systick.h" + +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/bmp.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/touchscreen.h" +#include "drivers/lcd/tft/fonts/dejavusans9.h" +#include "drivers/lcd/tft/fonts/dejavusansbold9.h" +#include "drivers/lcd/tft/fonts/dejavusansmono8.h" + +#include "drivers/lcd/icons16.h" + +// Color scheme +#define FONT_REGULAR &dejaVuSans9ptFontInfo +#define FONT_BOLD &dejaVuSansBold9ptFontInfo +#define COL_BACKGROUND COLOR_GRAY_80 +#define COL_TEXT COLOR_WHITE + +#define COL_BUTTON COLOR_GRAY_50 +#define COL_BUTTONBORDER COLOR_GRAY_50 +#define COL_BUTTONTEXT COLOR_WHITE +#define COL_BUTTONACTIVE COLOR_THEME_DEFAULT_BASE +#define COL_BUTTONACTIVEBORDER COLOR_THEME_DEFAULT_DARKER +#define COL_BUTTONACTIVETEXT COLOR_BLACK + +#define COL_MENU COLOR_GRAY_30 +#define COL_MENULIGHTER COLOR_GRAY_50 +#define COL_MENUTEXT COLOR_WHITE +#define COL_MENUACTIVE COLOR_THEME_DEFAULT_DARKER +#define COL_MENUACTIVELIGHTER COLOR_THEME_DEFAULT_BASE +#define COL_MENUACTIVETEXT COLOR_BLACK + +/**************************************************************************/ +/*! + Draws a single entry in the menu (adjusting the display depending + on whether the item is currently active or not) +*/ +/**************************************************************************/ +void renderMenuItem(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t headerWidth, bool active, char* headerText, char* bodyText) +{ + drawRectangleRounded(x, y, x+headerWidth, y+height, active ? COL_MENUACTIVE : COL_MENU, 10, DRAW_ROUNDEDCORNERS_NONE); + drawRectangleRounded(x+headerWidth, y, x+width, y+height, active ? COL_MENUACTIVELIGHTER : COL_MENULIGHTER, 10, DRAW_ROUNDEDCORNERS_NONE); + drawString(x+10, y+height/2, active ? COL_MENUACTIVETEXT : COL_MENUTEXT, FONT_BOLD, headerText); + drawString(x+headerWidth+25, y+height/2, active ? COL_MENUACTIVETEXT: COL_MENUTEXT, FONT_REGULAR, bodyText); + + if (active) + { + drawArrow(x+headerWidth+5, y+height/2, 7, DRAW_DIRECTION_LEFT, COL_MENUACTIVETEXT); + drawArrow(x+width-5, y+height/2, 7, DRAW_DIRECTION_RIGHT, COL_MENUACTIVETEXT); + } +} + +/**************************************************************************/ +/*! + Renders the 16x16 icons found in "/drivers/lcd/icons16.h" +*/ +/**************************************************************************/ +void renderIcons(void) +{ + // Cross/Failed + drawRectangleRounded(10, 190, 30, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(12, 192, COLOR_RED, icons16_failed); + drawRectangleRounded(10, 220, 30, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(12, 222, COLOR_RED, icons16_failed); + drawIcon16(12, 222, COLOR_WHITE, icons16_failed_interior); + drawRectangleRounded(10, 250, 30, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(12, 252, COLOR_WHITE, icons16_failed_interior); + + // Alert + drawRectangleRounded(40, 190, 60, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(42, 192, COLOR_YELLOW, icons16_alert); + drawRectangleRounded(40, 220, 60, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(42, 222, COLOR_YELLOW, icons16_alert); + drawIcon16(42, 222, COLOR_WHITE, icons16_alert_interior); + drawRectangleRounded(40, 250, 60, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(42, 252, COLOR_WHITE, icons16_alert_interior); + + // Checkmark/Passed + drawRectangleRounded(70, 190, 90, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(72, 192, COLOR_GREEN, icons16_passed); + drawRectangleRounded(70, 220, 90, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(72, 222, COLOR_GREEN, icons16_passed); + drawIcon16(72, 222, COLOR_WHITE, icons16_passed_interior); + drawRectangleRounded(70, 250, 90, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(72, 252, COLOR_WHITE, icons16_passed_interior); + + // Info + drawRectangleRounded(100, 190, 120, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(102, 192, COLOR_BLUE, icons16_info); + drawRectangleRounded(100, 220, 120, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(102, 222, COLOR_BLUE, icons16_info); + drawIcon16(102, 222, COLOR_WHITE, icons16_info_interior); + drawRectangleRounded(100, 250, 120, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(102, 252, COLOR_WHITE, icons16_info_interior); + + // Tools/Config + drawRectangleRounded(130, 190, 150, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(132, 192, COLOR_GREEN, icons16_tools); + + // Pointer + drawRectangleRounded(160, 190, 180, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(162, 192, COLOR_MAGENTA, icons16_pointer); + drawRectangleRounded(160, 220, 180, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(162, 222, COLOR_MAGENTA, icons16_pointer); + drawIcon16(162, 222, COLOR_WHITE, icons16_pointer_dot); + drawRectangleRounded(160, 250, 180, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(162, 252, COLOR_WHITE, icons16_pointer_dot); + + // Tag + drawRectangleRounded(190, 190, 210, 210, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(192, 192, COLOR_CYAN, icons16_tag); + drawRectangleRounded(190, 220, 210, 240, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(192, 222, COLOR_CYAN, icons16_tag); + drawIcon16(192, 222, COLOR_WHITE, icons16_tag_dot); + drawRectangleRounded(190, 250, 210, 270, COL_BUTTON, 5, DRAW_ROUNDEDCORNERS_ALL); + drawIcon16(192, 252, COLOR_WHITE, icons16_tag_dot); +} + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + #if !defined CFG_TFTLCD + #error "CFG_TFTLCD must be enabled in projectconfig.h for this test" + #endif + + // Configure cpu and mandatory peripherals + systemInit(); + + // Background + drawFill(COL_BACKGROUND); + + // Top/bottom action bars + drawRectangleFilled(0, 0, 239, 19, COL_MENU); + drawRectangleFilled(0, 280, 239, 319, COL_MENU); + + // Menu + drawRectangleRounded(6, 30, 232, 160, COL_MENU, 10, DRAW_ROUNDEDCORNERS_ALL); + drawString(20, 45, COL_MENUTEXT, FONT_BOLD, "SYSTEM SETTINGS"); + renderMenuItem(8, 65, 222, 23, 90, false, "LANGUAGE", "English"); + renderMenuItem(8, 90, 222, 23, 90, false, "TIMEZONE", "GMT+1"); + renderMenuItem(8, 115, 222, 23, 90, true, "SLEEP", "5 Minutes"); + + // Progress bar + drawProgressBar (70, 165, 160, 15, DRAW_ROUNDEDCORNERS_ALL, DRAW_ROUNDEDCORNERS_ALL, COL_MENU, COL_MENULIGHTER, COL_MENUACTIVE, COL_MENUACTIVELIGHTER, 72 ); + + // Render some icons + renderIcons(); + + // Action bar buttons + drawButton(5, 285, 75, 29, FONT_BOLD, 7, COL_BUTTONBORDER, COL_BUTTON, COL_BUTTONTEXT, "CANCEL"); + drawButton(160, 285, 75, 29, FONT_BOLD, 7, COL_BUTTONBORDER, COL_BUTTON, COL_BUTTONTEXT, "SAVE"); + + tsTouchData_t touch; + tsTouchError_t error; + + // Draw pixels whenever a touch screen event is detected + while (1) + { + // Wait for a valid touch event + error = tsWaitForEvent(&touch, 0); + if (!error) + { + drawPixel(touch.xlcd, touch.ylcd, COLOR_WHITE); + } + } + + return 0; +} diff --git a/tools/examples/lcd/tft/drawing_basic/main.c b/tools/examples/lcd/tft/drawing_basic/main.c new file mode 100644 index 0000000..f3468ab --- /dev/null +++ b/tools/examples/lcd/tft/drawing_basic/main.c @@ -0,0 +1,182 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include +#include +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/systick/systick.h" + +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/touchscreen.h" +#include "drivers/lcd/tft/dialogues/alphanumeric.h" + +#include "drivers/lcd/tft/fonts/dejavusans9.h" +#include "drivers/lcd/tft/fonts/dejavusansbold9.h" +#include "drivers/lcd/tft/fonts/dejavusansmono8.h" + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + #if !defined CFG_TFTLCD + #error "CFG_TFTLCD must be enabled in projectconfig.h for this test" + #endif + #if defined CFG_INTERFACE + #error "CFG_INTERFACE must be disabled in projectconfig.h for this test (to save space)" + #endif + + // Clear the screen + // --------------------------------------------------------------------- + drawFill(COLOR_WHITE); + + // Render some text using DejaVu Sans 9 and Sans Mono 8 + // --------------------------------------------------------------------- + drawString(5, 10, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "DejaVu Sans 9 Bold"); + drawString(5, 30, COLOR_BLACK, &dejaVuSans9ptFontInfo, "DejaVu Sans 9"); + drawString(5, 50, COLOR_BLACK, &dejaVuSansMono8ptFontInfo, "DejaVu Sans Mono 8"); + + // Change the LCD orientation to render text horizontally + // --------------------------------------------------------------------- + lcdProperties_t lcdProperties = lcdGetProperties(); + // Check if the screen orientation can be changed + if (lcdProperties.orientation) + { + // Change the orientation + lcdSetOrientation(lcdGetOrientation() == LCD_ORIENTATION_PORTRAIT ? + LCD_ORIENTATION_LANDSCAPE : LCD_ORIENTATION_PORTRAIT); + // Render some text in the new orientation + drawString(5, 10, COLOR_BLACK, &dejaVuSans9ptFontInfo, "DejaVu Sans 9 (Rotated)"); + // Change the orientation back + lcdSetOrientation(lcdGetOrientation() == LCD_ORIENTATION_PORTRAIT ? + LCD_ORIENTATION_LANDSCAPE : LCD_ORIENTATION_PORTRAIT); + } + + // Draw some primitive shapes + // --------------------------------------------------------------------- + drawLine(5, 65, 200, 65, COLOR_RED); + drawLine(5, 67, 200, 67, COLOR_GREEN); + drawLine(5, 69, 200, 69, COLOR_BLUE); + drawCircleFilled(30, 105, 25, COLOR_BLACK); + drawCircleFilled(30, 105, 23, drawRGB24toRGB565(0x33, 0x00, 0x00)); + drawCircleFilled(30, 105, 19, drawRGB24toRGB565(0x66, 0x00, 0x00)); + drawCircleFilled(30, 105, 15, drawRGB24toRGB565(0x99, 0x00, 0x00)); + drawCircleFilled(30, 105, 11, drawRGB24toRGB565(0xCC, 0x00, 0x00)); + drawCircleFilled(30, 105, 7, drawRGB24toRGB565(0xFF, 0x00, 0x00)); + drawRectangleFilled( 80, 80, 180, 125, COLOR_DARKERGRAY); + drawRectangleFilled( 85, 85, 175, 120, COLOR_DARKGRAY); + drawRectangleFilled( 90, 90, 170, 115, COLOR_MEDIUMGRAY); + drawRectangleFilled( 95, 95, 165, 110, COLOR_LIGHTGRAY); + drawRectangleFilled(100, 100, 160, 105, COLOR_PALEGRAY); + + // Draw some compound shapes + // --------------------------------------------------------------------- + drawProgressBar(70, 140, 75, 12, COLOR_BLACK, COLOR_MEDIUMGRAY, 78); + drawString(5, 144, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "Progress"); + drawString(155, 144, COLOR_BLACK, &dejaVuSans9ptFontInfo, "78%"); + drawRectangleFilled(0, 175, 239, 210, COLOR_DARKERGRAY); + drawButton(20, 180, 200, 25, &dejaVuSans9ptFontInfo, 7, "Click For Text Entry", false); + + // Wait for a valid touch event + // --------------------------------------------------------------------- + tsTouchData_t data; + tsTouchError_t error = -1; + bool success = false; + while(!success) + { + // Wait forever for a valid touch event to occur (ignoring faulty readings) + while (error) + { + // Only exit this loop when '0' is returned + error = tsWaitForEvent(&data, 0); + // printf("Error: %d X: %u Y: %u \r\n", error, data.x, data.y); + } + + // Reset error to an error state in case we got a valid reading, but it's not + // within the expected range + error = -1; + + // Check if the captured touch event is within the specified X/Y range + if (data.x > 20 && data.x < 220 && data.y > 180 && data.y < 205) + { + // Wait a few milliseconds then display the text input dialogue + systickDelay(100); + char* results = alphaShowDialogue(); + // At this point, results contains the text from the dialogue ... + // clear the screen and show the results + drawFill(COLOR_WHITE); + drawString(10, 10, COLOR_BLACK, &dejaVuSans9ptFontInfo, "You Entered:"); + drawString(10, 30, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, results); + drawString(10, 155, COLOR_BLACK, &dejaVuSans9ptFontInfo, "Thanks ... starting blinky!"); + // Setting success to true allow the code to move in to blinky + success = true; + } + } + + uint32_t currentSecond, lastSecond; + currentSecond = lastSecond = 0; + + while (1) + { + // Toggle LED once per second ... rollover = 136 years :) + currentSecond = systickGetSecondsActive(); + if (currentSecond != lastSecond) + { + lastSecond = currentSecond; + if (gpioGetValue(CFG_LED_PORT, CFG_LED_PIN) == CFG_LED_OFF) + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); + } + else + { + gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF); + } + } + } + + return 0; +} diff --git a/tools/examples/lcd/tft/oscilloscope/main.c b/tools/examples/lcd/tft/oscilloscope/main.c new file mode 100644 index 0000000..8c0f37b --- /dev/null +++ b/tools/examples/lcd/tft/oscilloscope/main.c @@ -0,0 +1,273 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/adc/adc.h" +#include "core/systick/systick.h" + +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/touchscreen.h" +#include "drivers/lcd/tft/fonts/dejavusans9.h" +#include "drivers/lcd/tft/fonts/dejavusansbold9.h" + +static uint8_t adcBuffer[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static uint8_t digBuffer[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +bool adcEnabled = true; +bool digEnabled = false; + +/**************************************************************************/ +/*! + Renders the frame around the data grid +*/ +/**************************************************************************/ +void renderLCDFrame(void) +{ + // Clear the screen + drawFill(COLOR_DARKGRAY); + + // Render V references + drawString(245, 27, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "3.5V"); + drawString(244, 26, COLOR_WHITE, &dejaVuSansBold9ptFontInfo, "3.5V"); + drawString(245, 195, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "0.0V"); + drawString(244, 194, COLOR_WHITE, &dejaVuSansBold9ptFontInfo, "0.0V"); + + // Div settings + drawString( 10, 10, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "~100ms/Div"); + drawString( 9, 9, COLOR_WHITE, &dejaVuSansBold9ptFontInfo, "~100ms/Div"); + drawString( 95, 10, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "500mV/Div"); + drawString( 94, 9, COLOR_WHITE, &dejaVuSansBold9ptFontInfo, "500mV/Div"); + + // Clear the ADC output level just in case + drawRectangleFilled(175, 5, 250, 18, COLOR_DARKGRAY); + + // Render the channel text + drawString( 25, 220, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "P1.4 (Analog)"); + drawString( 24, 219, adcEnabled ? COLOR_YELLOW : COLOR_MEDIUMGRAY, &dejaVuSansBold9ptFontInfo, "P1.4 (Analog)"); + drawString(135, 220, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "P2.0 (Digital)"); + drawString(134, 219, digEnabled ? COLOR_GREEN : COLOR_MEDIUMGRAY, &dejaVuSansBold9ptFontInfo, "P2.0 (Digital)"); + + // ADC Warning + drawString(245, 80, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, "Warning:"); + drawString(244, 79, COLOR_WHITE, &dejaVuSansBold9ptFontInfo, "Warning:"); + drawString(244, 95, COLOR_WHITE, &dejaVuSans9ptFontInfo, "ADC input"); + drawString(244, 110, COLOR_WHITE, &dejaVuSans9ptFontInfo, "is not 5.0V"); + drawString(244, 125, COLOR_WHITE, &dejaVuSans9ptFontInfo, "tolerant!"); +} + +/**************************************************************************/ +/*! + Converts the supplied 8-bit value to an approximate pixel height in + the data grid +*/ +/**************************************************************************/ +uint16_t adcValToPixel(uint8_t value) +{ + // Since the chart is 175 pixels high and 3.3V is at + // approximately 165 pixels height, we need to + // divide the 8 bit ADC readings by 1.545 (255/165) + // using fixed point math, and then substract + // the number from the bottom of the frame + uint16_t pixel = 0; + pixel = 200 - (value * 1000 / 1545); + return pixel; +} + +/**************************************************************************/ +/*! + Redraws the grid and renders the data points on the LCD +*/ +/**************************************************************************/ +void renderLCDGrid(void) +{ + if ((!adcEnabled) && (!digEnabled)) + { + return; + } + + // Redraw the grid + drawRectangle(9, 24, 236, 201, COLOR_LIGHTGRAY); + drawRectangleFilled(10, 25, 235, 200, COLOR_BLACK); + + // Horizontal lines + drawLine(10, 50, 235, 50, COLOR_DARKERGRAY); + drawLine(10, 75, 235, 75, COLOR_DARKERGRAY); + drawLine(10, 100, 235, 100, COLOR_DARKERGRAY); + drawLine(10, 125, 235, 125, COLOR_DARKERGRAY); + drawLine(10, 150, 235, 150, COLOR_DARKERGRAY); + drawLine(10, 175, 235, 175, COLOR_DARKERGRAY); + + // Vertical lines + drawLine( 35, 25, 35, 200, COLOR_DARKERGRAY); + drawLine( 60, 25, 60, 200, COLOR_DARKERGRAY); + drawLine( 85, 25, 85, 200, COLOR_DARKERGRAY); + drawLine(110, 25, 110, 200, COLOR_DARKERGRAY); + drawLine(135, 25, 135, 200, COLOR_DARKERGRAY); + drawLine(160, 25, 160, 200, COLOR_DARKERGRAY); + drawLine(185, 25, 185, 200, COLOR_DARKERGRAY); + drawLine(210, 25, 210, 200, COLOR_DARKERGRAY); + + // Render the individual data points + uint32_t counter; + for (counter = 0; counter < 9; counter++) + { + // Draw historical data + uint32_t arrayPosition = 9 - counter; + + // Draw analog data points (Yellow) + if (adcEnabled) + { + drawLine(10 + counter * 25, adcValToPixel(adcBuffer[arrayPosition]), 10 + (counter + 1) * 25, adcValToPixel(adcBuffer[arrayPosition - 1]), COLOR_YELLOW); + } + + // Draw digital data points (Green) + if (digEnabled) + { + drawLine(10 + counter * 25, adcValToPixel(digBuffer[arrayPosition]), 10 + (counter + 1) * 25, adcValToPixel(digBuffer[arrayPosition - 1]), COLOR_GREEN); + } + } + + // Render ADC value in text if present + if (adcEnabled) + { + char text[10]; + // Assuming 3.3V supply and 8-bit ADC values, 1 unit = 12.89mV (3300/256) + sprintf(text, "%u.%u V", ((adcBuffer[0] * 1289) / 100) / 1000, ((adcBuffer[0] * 1294) / 100) % 1000); + // Clear the previous text + drawRectangleFilled(175, 5, 250, 18, COLOR_DARKGRAY); + // Render the latest value in mV + drawString(180, 10, COLOR_BLACK, &dejaVuSansBold9ptFontInfo, text); + drawString(179, 9, COLOR_YELLOW, &dejaVuSansBold9ptFontInfo, text); + } +} + +/**************************************************************************/ +/*! + Shifts the buffer contents right one byte, and inserts the latest + value at the beginning. +*/ +/**************************************************************************/ +void addToBuffer(uint8_t *buffer, uint8_t value) +{ + uint32_t counter; + for (counter = 9; counter > 0; counter--) + { + buffer[counter] = buffer[counter - 1]; + } + + // Append the latest value + buffer[0] = value; +} + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + #if !defined CFG_TFTLCD + #error "CFG_TFTLCD must be enabled in projectconfig.h for this test" + #endif + #if defined CFG_INTERFACE + #error "CFG_INTERFACE must be disabled in projectconfig.h for this test (to save space)" + #endif + + // Configure cpu and mandatory peripherals + systemInit(); + + /* Set P2.0 to GPIO input (just in case) */ + gpioSetDir(2, 0, 0); + + /* Set P1.4/AD5 to analog input (only AD0..3 are configured by adcInit) */ + IOCON_PIO1_4 &= ~(IOCON_PIO1_4_ADMODE_MASK | + IOCON_PIO1_4_FUNC_MASK | + IOCON_PIO1_4_MODE_MASK); + IOCON_PIO1_4 |= (IOCON_PIO1_4_FUNC_AD5 & + IOCON_PIO1_4_ADMODE_ANALOG); + + // Rotate the screen and render the area around the data grid + lcdSetOrientation(LCD_ORIENTATION_LANDSCAPE); + renderLCDFrame(); + + tsTouchData_t touch; + + // Start reading + while (1) + { + // Wait up to 5ms for a touch event + tsTouchError_t error = tsWaitForEvent(&touch, 5); + if (!error) + { + if (touch.x > 25 && touch.x < 100 && touch.y > 210) + { + // Analog switch selected + adcEnabled = adcEnabled ? false : true; + } + if (touch.x > 125 && touch.x < 200 && touch.y > 210) + { + // Digital switch selected + digEnabled = digEnabled ? false : true; + } + // Refresh the frame + renderLCDFrame(); + } + + // Read pins + if (adcEnabled) + addToBuffer(adcBuffer, adcRead(5) / 4); // 10-bit value converted to 8-bits + if (digEnabled) + addToBuffer(digBuffer, gpioGetValue(2, 0) ? 0xFF : 0x00); + + // Update the LCD is required + renderLCDGrid(); + + // Note, this will actually mean the timing is ~100mS + the amount of + // time it took to get the readings and update the LCD + // A timer interrupt could be used to get much more accurate results, + // filling the buffer inside the IRQ and rendering the screen updates + // every x milliseconds + systickDelay(100); + } + + return 0; +} diff --git a/tools/examples/lcd/tft/oscilloscope/readme.txt b/tools/examples/lcd/tft/oscilloscope/readme.txt new file mode 100644 index 0000000..e50a9d2 --- /dev/null +++ b/tools/examples/lcd/tft/oscilloscope/readme.txt @@ -0,0 +1,38 @@ +OVERVIEW +============================================================ +This examples simulates a very crude oscilloscope, and +reads the values on an analog input pin (P1.4/Wakeup, which +can be configured as AD5) as well as a digital pin (P2.0). +The digital pin will simply be displayed as 'High' (3.3V) +or 'Low' (0V/GND). + +The last 10 readings are rendered in a data grid on the LCD, +with new readings added approximately every 100ms. + +This sample demonstrates the following features +============================================================ + +- Rotating the LCD orientation +- Rendering text with different colors and fonts +- Using the touch screen to enable or disable a feature + +WARNING +============================================================ +Please note that the ADC pins on the LPC1343 are NOT 5.0V +tolerant. Supply more than 3.3V to an ADC pin will +permanently damage the MCU. Digital I/O pins are 5.0V +tolerant and can safely test 5.0V logic. + +Pin Usage +============================================================ +This examples is based on the LPC1343 TFT LCD Stand-Alone +board, which has a very limited number of pins broken out. +P1.4 can be configure as GPIO, but also as WAKEUP and AD5. + +This pin is also available on the LPC1343 Reference Design +Base Base and is marked as WAKEUP on the PCB, but it has +a 10K pullup on it to allow the pin to function as a WAKEUP +source. + +For details on the differences between these boards, see +the schematics available in the ~/tools/schematics folder. \ No newline at end of file diff --git a/tools/examples/lcd/tft/touchscreen/main.c b/tools/examples/lcd/tft/touchscreen/main.c new file mode 100644 index 0000000..2c75e78 --- /dev/null +++ b/tools/examples/lcd/tft/touchscreen/main.c @@ -0,0 +1,81 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/gpio/gpio.h" +#include "core/adc/adc.h" +#include "core/systick/systick.h" + +#include "drivers/lcd/tft/lcd.h" +#include "drivers/lcd/tft/drawing.h" +#include "drivers/lcd/tft/touchscreen.h" +#include "drivers/lcd/tft/fonts/dejavusans9.h" +#include "drivers/lcd/tft/fonts/dejavusansbold9.h" + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + #if !defined CFG_TFTLCD + #error "CFG_TFTLCD must be enabled in projectconfig.h for this test" + #endif + + // Configure cpu and mandatory peripherals + systemInit(); + + tsTouchData_t touch; + tsTouchError_t error; + + // Start reading + while (1) + { + // Wait for a valid touch event + error = tsWaitForEvent(&touch, 0); + if (!error) + { + drawCircleFilled(touch.xlcd, touch.ylcd, 2, COLOR_WHITE); + } + } + + return 0; +} diff --git a/tools/examples/lcd/tft/touchscreen/readme.txt b/tools/examples/lcd/tft/touchscreen/readme.txt new file mode 100644 index 0000000..8860bc6 --- /dev/null +++ b/tools/examples/lcd/tft/touchscreen/readme.txt @@ -0,0 +1,11 @@ +OVERVIEW +============================================================ +This example continually samples the touch screen and +whenever a valid reading occurs draws a pixel at the +corresponding X/Y position. + +This sample demonstrates the following features +============================================================ + +- Waiting for a valid TS reading (ignoring X/Y mismatches) +- Getting the X/Y position from TS events diff --git a/tools/examples/readme.txt b/tools/examples/readme.txt new file mode 100644 index 0000000..d1685f3 --- /dev/null +++ b/tools/examples/readme.txt @@ -0,0 +1,4 @@ +This folder contains various examples showing how to use the LPC1343 to +accomplish certain tasks or how to use it with external devices, such as +communicating with the PC using USB HID, etc. + diff --git a/tools/examples/sensors/pn532/ISO14443A_ID/main.c b/tools/examples/sensors/pn532/ISO14443A_ID/main.c new file mode 100644 index 0000000..fb6066e --- /dev/null +++ b/tools/examples/sensors/pn532/ISO14443A_ID/main.c @@ -0,0 +1,141 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "drivers/sensors/pn532/pn532.h" +#include "drivers/sensors/pn532/pn532_drvr.h" + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. + + Note: CFG_INTERFACE is normally enabled by default. If you wish to + enable the blinking LED code in main, you will need to open + projectconfig.h, comment out "#define CFG_INTERFACE" and + rebuild the project. +*/ +/**************************************************************************/ +int main (void) +{ + #ifdef CFG_INTERFACE + #error "CFG_INTERFACE must be disabled in projectconfig.h for this demo" + #endif + #if !defined CFG_PRINTF_USBCDC + #error "CFG_PRINTF_USBCDC must be enabled in projectconfig.h for this demo" + #endif + + // Configure cpu and mandatory peripherals + systemInit(); + + // Wait 5 second for someone to open the USB connection for printf + systickDelay(5000); + + // Initialise the PN532 + pn532Init(); + + byte_t response[256]; + size_t responseLen; + pn532_error_t error; + + // Setup command to initialise a single ISO14443A target at 106kbps + byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS }; + + while (1) + { + printf("%s", CFG_PRINTF_NEWLINE); + printf("Wait for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE); + + // Send the command + error = pn532Write(abtCommand, sizeof(abtCommand)); + + // Wait until we get a response or an unexpected error message + do + { + error = pn532Read(response, &responseLen); + systickDelay(25); + } + #ifdef PN532_UART + while (error == PN532_ERROR_RESPONSEBUFFEREMPTY); + #endif + #ifdef PN532_SPI + while ((error == PN532_ERROR_RESPONSEBUFFEREMPTY) || (error = PN532_ERROR_SPIREADYSTATUSTIMEOUT)); + #endif + + // Print the card details if possible + if (!error) + { + /* Response for ISO14443A 106KBPS (Mifare Classic, etc.) + See UM0701-02 section 7.3.5 for more information + + byte Description + ------------- ------------------------------------------ + b7 Tags Found + b8 Tag Number (only one used in this example) + b9..10 SENS_RES + b11 SEL_RES + b12 NFCID Length + b13..NFCIDLen NFCID + + SENS_RES SEL_RES Manufacturer/Card Type NFCID Len + -------- ------- ----------------------- --------- + 00 04 08 NXP Mifare Classic 1K 4 bytes */ + + printf("%s", CFG_PRINTF_NEWLINE); + printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE); + printf("%-12s: ", "NFCID"); + size_t pos; + for (pos=0; pos < response[12]; pos++) + { + printf("%02x ", response[13 + pos]); + } + printf(CFG_PRINTF_NEWLINE); + } + else + { + // Oops .... something bad happened. Check 'error' + printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE); + } + + // Wait at least one second before trying again + systickDelay(1000); + } +} diff --git a/tools/examples/sensors/pn532/ISO14443A_ID/readme.txt b/tools/examples/sensors/pn532/ISO14443A_ID/readme.txt new file mode 100644 index 0000000..020a1fd --- /dev/null +++ b/tools/examples/sensors/pn532/ISO14443A_ID/readme.txt @@ -0,0 +1,30 @@ +OVERVIEW +============================================================ +This example will wait for an ISO14443A card to enter +the RF field, and then try to determine the specific card +model (SENS_RES and SEL_RES) as well as the card's NFCID. + +All information will be sent to USBCDC by default, with the +PN532 breakout board connected via UART. + +HOW TO USE THIS EXAMPLE +============================================================ +1.) Connect the PN532 NFC Breakout Board to UART on the + LPC1343 as follows: + + PN532 LPC1343 + ----- ------- + GND GND + TXD RXD + RXD TXD + 3.3V 3.3V + +2.) Configure your terminal software to open the USB COM + port at 115K. + +3.) When the application starts, there is a 5 second delay + (to allow you time to connect via USB CDC), after which + point the device will wait for a single ISO14443A card + (Mifare Classic, etc.) and try to read it's ID. Once a + card is found, the reader will start looking again for a + card after a 1 second delay. diff --git a/tools/examples/sensors/tsl2561/main.c b/tools/examples/sensors/tsl2561/main.c new file mode 100644 index 0000000..5f2fda3 --- /dev/null +++ b/tools/examples/sensors/tsl2561/main.c @@ -0,0 +1,70 @@ +/**************************************************************************/ +/*! + @file main.c + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2011, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#include + +#include "projectconfig.h" +#include "sysinit.h" + +#include "core/systick/systick.h" +#include "drivers/sensors/tsl2561/tsl2561.h" + +/**************************************************************************/ +/*! + Main program entry point. After reset, normal code execution will + begin here. +*/ +/**************************************************************************/ +int main(void) +{ + // Configure cpu and mandatory peripherals + systemInit(); + + uint16_t lumMixed, lumInfrared; + + while (1) + { + // Read mixed and infrared luminosity from tsl2561 + tsl2561GetLuminosity(&lumMixed, &lumInfrared); + + // Display the readings + printf("Luminosity: \r\n Broadband (Visible + IR) - %d \r\n Infrared - %d \r\n", lumMixed, lumInfrared); + + // Wait 1 second between reading + systickDelay(1000); + } + + return 0; +} diff --git a/tools/examples/sensors/tsl2561/readme.txt b/tools/examples/sensors/tsl2561/readme.txt new file mode 100644 index 0000000..7c922bd --- /dev/null +++ b/tools/examples/sensors/tsl2561/readme.txt @@ -0,0 +1,2 @@ +Reads the mixed (visible + UV) and UV only luminosity levels +using the TSL2561 digital light sensor. \ No newline at end of file diff --git a/tools/lpcrc/Makefile b/tools/lpcrc/Makefile new file mode 100644 index 0000000..6957146 --- /dev/null +++ b/tools/lpcrc/Makefile @@ -0,0 +1,12 @@ +CC = gcc +LD = gcc +LDFLAGS = -Wall -O4 -std=c99 +EXES = lpcrc + +all: $(EXES) + +% : %.c + $(LD) $(LDFLAGS) -o $@ $< + +clean: + rm -f $(EXES) diff --git a/tools/lpcrc/bin/lpcrc-linux b/tools/lpcrc/bin/lpcrc-linux new file mode 100644 index 0000000..a6c1aa4 Binary files /dev/null and b/tools/lpcrc/bin/lpcrc-linux differ diff --git a/tools/lpcrc/bin/lpcrc.exe b/tools/lpcrc/bin/lpcrc.exe new file mode 100644 index 0000000..d4ccd6f Binary files /dev/null and b/tools/lpcrc/bin/lpcrc.exe differ diff --git a/tools/lpcrc/lpcrc.c b/tools/lpcrc/lpcrc.c new file mode 100644 index 0000000..ed316b2 --- /dev/null +++ b/tools/lpcrc/lpcrc.c @@ -0,0 +1,97 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2010, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#define BLOCK_COUNT 7 +#define BLOCK_LENGTH 4 +#define BLOCK_TOTAL (BLOCK_COUNT*BLOCK_LENGTH) + +typedef unsigned char byte_t; + +int main(int argc, char *argv[]) +{ + FILE* pf; + byte_t buf[BLOCK_TOTAL]; + uint32_t crc = 0; + uint32_t block; + + // Check for required arguments + if (argc < 2) + { + printf("syntax: lpcrc \n"); + return 1; + } + + // Try to open the supplied firmware + if ((pf = fopen(argv[1],"rb+")) == NULL) + { + printf("error: could not open file [%s] with write access\n",argv[1]); + return 1; + } + + // Read out the data blocks used for crc calculation + if (fread(buf,1,BLOCK_TOTAL,pf) != BLOCK_TOTAL) + { + printf("error: could not read required bytes\n"); + fclose(pf); + return 1; + } + + // Compute the crc value + for (block=0; block +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORTBUFSIZE 32 +#define BUFSIZE 1024 +#define PACKET_FCS 2 +#define DEBUG 1 +#define PIPENAME "/tmp/wireshark" +#define BAUDRATE B115200 + +enum FSM +{ + START_CAPTURE, + PACKET_CAPTURE +}; + +static int FD_pipe = -1; +static int FD_com = -1; +static uint8_t port_buf[PORTBUFSIZE]; +static uint8_t circ_buf[BUFSIZE]; +static uint16_t rd_idx = 0; +static uint16_t wr_idx = 0; +static uint8_t len; +static uint8_t state = START_CAPTURE; +static uint8_t file_write = 0; + +/**************************************************************************/ +/*! + Open the serial port that we'll be communicating with the Freakduino (sniffer) + through. +*/ +/**************************************************************************/ +static int serial_open(char *portname) +{ + int FD_com; // file descriptor for the serial port + struct termios term; + + FD_com = open(portname, O_RDONLY | O_NOCTTY | O_NDELAY); + + if(FD_com == -1) // if open is unsucessful + { + printf("serial_open: Unable to open %s.\n", portname); + } + else + { + // set speed of port + cfsetspeed(&term, BAUDRATE); + + // set to 8-bits, no parity, 1 stop bit + term.c_cflag &= ~PARENB; + term.c_cflag &= ~CSTOPB; + term.c_cflag &= ~CSIZE; + term.c_cflag |= CS8; + + term.c_cflag |= (CLOCAL | CREAD); + tcsetattr(FD_com, TCSANOW, &term); + } + return(FD_com); +} + +/**************************************************************************/ +/*! + Create the named pipe that we will be communicating with wireshark through. +*/ +/**************************************************************************/ +static void named_pipe_create(char *name) +{ + int rv = 0; + rv = mkfifo(name, 0666); + if ((rv == -1) && (errno != EEXIST)) + { + perror("Error creating named pipe"); + exit(1); + } + + FD_pipe = open(name, O_WRONLY); + + if (FD_pipe == -1) + { + perror("Error connecting to named pipe"); + exit(1); + } +} + +/**************************************************************************/ +/*! + Write data to the pipe +*/ +/**************************************************************************/ +size_t data_write(const void *ptr, size_t size) +{ + ssize_t bytes = 0; + if (FD_pipe != -1) + { + bytes = write(FD_pipe, ptr, size); + } +} + +/**************************************************************************/ +/*! + Write the global header to wireshark. This is only done once at the + beginning of the capture. +*/ +/**************************************************************************/ +static void write_global_hdr() +{ + uint32_t magic_number = 0xa1b2c3d4; /* magic number */ + uint16_t version_major = 2; /* major version number */ + uint16_t version_minor = 4; /* minor version number */ + int32_t thiszone = 0; /* GMT to local correction */ + uint32_t sigfigs = 0; /* accuracy of timestamps */ + uint32_t snaplen = 65535; /* max length of captured packets, in octets */ + uint32_t network = 195; /* data link type (DLT) - IEEE 802.15.4 */ + + data_write(&magic_number, sizeof(magic_number)); + data_write(&version_major, sizeof(version_major)); + data_write(&version_minor, sizeof(version_minor)); + data_write(&thiszone, sizeof(thiszone)); + data_write(&sigfigs, sizeof(sigfigs)); + data_write(&snaplen, sizeof(snaplen)); + data_write(&network, sizeof(network)); +} + +/**************************************************************************/ +/*! + Write the frame header into wireshark. This is required for the libpcap + format and informs wireshark that a new frame is coming. +*/ +/**************************************************************************/ +static void write_frame_hdr(uint8_t len) +{ + uint32_t ts_sec; /* timestamp seconds */ + uint32_t ts_usec; /* timestamp microseconds */ + uint32_t incl_len; /* number of octets of packet saved in file */ + uint32_t orig_len; /* actual length of packet */ + struct timeval tv; + + gettimeofday(&tv, NULL); + ts_sec = tv.tv_sec; + ts_usec = tv.tv_usec; + incl_len = len; + orig_len = len + PACKET_FCS; + + data_write(&ts_sec, sizeof(ts_sec)); + data_write(&ts_usec, sizeof(ts_usec)); + data_write(&incl_len, sizeof(incl_len)); + data_write(&orig_len, sizeof(orig_len)); +} + +/**************************************************************************/ +/*! + Write one frame into wireshark (via the pipe). +*/ +/**************************************************************************/ +static void write_frame(uint8_t frame_len) +{ + uint8_t i; + + // actual frame length for wireshark should not include FCS + frame_len -= PACKET_FCS; + + // write header to inform WS that new frame has arrived + write_frame_hdr(frame_len); + + // bump rd_idx. we don't want to write the length byte + rd_idx = (rd_idx + 1) % BUFSIZE; + + // write frame into wireshark + for (i=0; i wr_idx) + { + // read index is greater than write. we must have wrapped around + return (BUFSIZE - (rd_idx - wr_idx)); + } + else + { + return (wr_idx - rd_idx); + } +} + +/**************************************************************************/ +/*! + Deal with any received signals. This includes ctrl-C to stop the program. +*/ +/**************************************************************************/ +static void sig_int(int signo) +{ + (void) signo; + if (FD_pipe != -1) + { + printf("\nClosing pipe.\n"); + close(FD_pipe); + } + + if (FD_com != -1) + { + printf("\nClosing serial port.\n"); + close(FD_com); + } + + printf("\nSignal captured and devices shut down.\n"); + + exit(0); +} + +/**************************************************************************/ +/*! + Init the signals we'll be checking for. +*/ +/**************************************************************************/ +static void signal_init(void) +{ + signal(SIGINT, sig_int); + signal(SIGHUP, sig_int); + signal(SIGTERM, sig_int); +} + +/**************************************************************************/ +/*! + Here's the meat of the code. +*/ +/**************************************************************************/ +int main(int argc, char *argv[]) +{ + int nbytes; + uint8_t i; + + // capture any signals that will terminate program + signal_init(); + + // make sure the COM port is specified + if (argc == 2) + { + // open the COM port + if ((FD_com = serial_open(argv[1])) == -1) + { + printf("Serial port not opened.\n"); + return 0; + } + else + { + printf("Serial port connected. Waiting for wireshark connection.\n"); + printf("Open wireshark and connect to local interface: %s\n", PIPENAME); + } + } + else + { + printf("Usage: wsbridge .\n"); + return 0; + } + + + // create and open pipe for wireshark + named_pipe_create(PIPENAME); + + // wait for wireshark to connect to pipe. Once wireshark + // connects, then the global header will be written to it. + if (FD_pipe != -1) + { + write_global_hdr(); + printf("Client connected to pipe.\n"); + } + + for (;;) + { + uint16_t bytes_in_buf; + uint8_t frame_len, byte_ctr; + + // wait for data to come in on the serial port + if ((nbytes = read(FD_com, port_buf, PORTBUFSIZE)) > 0) + { + // write data to circular buffer. loop through all received bytes + for (i=0; i frame_len) + { + // if more than one frame is available, then write one frame to + // wireshark and then see if any more are available. + write_frame(frame_len); + } + else if (bytes_in_buf == frame_len) + { + // only one frame is available. write to wireshark and then quit + // the loop + write_frame(frame_len); + file_write = 0; + } + else + { + // less than one frame is available. quit the loop and collect more + // bytes. we normally should not get here. + file_write = 0; + } + } + } + } +} + diff --git a/tools/wsbridge/v0.50/Win/wsbridge.sln b/tools/wsbridge/v0.50/Win/wsbridge.sln new file mode 100644 index 0000000..43470d2 --- /dev/null +++ b/tools/wsbridge/v0.50/Win/wsbridge.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsbridge", "wsbridge\wsbridge.csproj", "{9CAFA529-8FF4-42D4-B6A6-54992B3BB40F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9CAFA529-8FF4-42D4-B6A6-54992B3BB40F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CAFA529-8FF4-42D4-B6A6-54992B3BB40F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CAFA529-8FF4-42D4-B6A6-54992B3BB40F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CAFA529-8FF4-42D4-B6A6-54992B3BB40F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/wsbridge/v0.50/Win/wsbridge.suo b/tools/wsbridge/v0.50/Win/wsbridge.suo new file mode 100644 index 0000000..00ead54 Binary files /dev/null and b/tools/wsbridge/v0.50/Win/wsbridge.suo differ diff --git a/tools/wsbridge/v0.50/Win/wsbridge/Program.cs b/tools/wsbridge/v0.50/Win/wsbridge/Program.cs new file mode 100644 index 0000000..98e7c49 --- /dev/null +++ b/tools/wsbridge/v0.50/Win/wsbridge/Program.cs @@ -0,0 +1,305 @@ +using System; +using System.IO; +using System.IO.Ports; +using System.IO.Pipes; + +namespace wsbridge +{ + class Program + { + static NamedPipeServerStream wspipe; + static BinaryWriter ws; + static SerialPort p; + const uint BUFSIZE = 1024; + static byte[] b = new byte[BUFSIZE]; + static uint wr_idx = 0; + static uint rd_idx = 0; + static byte len; + static FSM state; + static bool file_write = false; + static long start_time_in_ticks; + static byte byte_ctr; + static String port; + + enum FSM + { + START_CAPTURE, + PACKET_CAPTURE + } + + const int PACKET_FCS = 2; + const int PACKET_LEN = 1; + const bool DEBUG_PRINT = true; + + static void Main(string[] args) + { + // Commane line options + if (args.Length == 0) + { + // generate list of active serial ports + string[] names = SerialPort.GetPortNames(); + Console.WriteLine("Serial ports:"); + foreach (string name in names) Console.WriteLine(name); + Console.Write("Choose one:"); + port = Console.ReadLine(); + } + else if (args.Length == 1) + { + port = args[0]; + } + else + { + Console.WriteLine("Usage: wsbridge "); + Console.WriteLine("or leave portname blank for a list of ports."); + Environment.Exit(0); + } + + // Open serial port + try + { + p = new SerialPort(port, 115200, Parity.None, 8, StopBits.One); + p.Open(); + } + catch (Exception e) + { + // ooops, serial port can't be opened. throw exception, print message, and exit + Console.WriteLine("Error opening serial port. Msg = " + e.Message); + Environment.Exit(0); + } + Console.WriteLine("Serial port opened successfully."); + + // create pipe + try + { + wspipe = new NamedPipeServerStream("wireshark", PipeDirection.Out); + } + catch (Exception e) + { + Console.WriteLine("Error opening pipe. Msg = " + e.Message); + p.Close(); + Environment.Exit(0); + } + + // wait for wireshark to connect to pipe + Console.WriteLine("Waiting for connection to wireshark."); + Console.WriteLine("Open wireshark and connect to interface: Local:\\\\.\\pipe\\wireshark"); + wspipe.WaitForConnection(); + Console.WriteLine("Client connected."); + + // connect binary writer to pipe to write binary data into it + ws = new BinaryWriter(wspipe); + + // add serial data capture + p.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived); + state = FSM.START_CAPTURE; + + // keep track of time started. this will be used for timestamps + start_time_in_ticks = DateTime.Now.Ticks; + + // generate header to identify the packet capture + write_global_hdr(); + + // run forever + while (true) + { + } + } + + // serial port handler. this gets executed whenever data is available on the serial port + static void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) + { + uint frame_len, bytes_in_buf; + + // loop until serial port buffer is empty + while (p.BytesToRead != 0) + { + switch (state) + { + case FSM.START_CAPTURE: + // starting a new frame. the first byte will indicate the length + len = (byte)p.ReadByte(); + b[wr_idx] = len; + byte_ctr = 0; + + if (DEBUG_PRINT) + { + Console.WriteLine(); + Console.Write(String.Format("{0,2:X}", b[wr_idx]) + ' '); + } + + // increment the buffer index and wrap back to 0 if it reaches the max size + // (standard circular buffer behavior) + wr_idx = (wr_idx + 1) % BUFSIZE; + state = FSM.PACKET_CAPTURE; + break; + + case FSM.PACKET_CAPTURE: + // capture bytes until the total length of the frame + b[wr_idx] = (byte)p.ReadByte(); + + if (DEBUG_PRINT) + { + Console.Write(String.Format("{0,2:X}", b[wr_idx]) + ' '); + } + + wr_idx = (wr_idx + 1) % BUFSIZE; + byte_ctr++; + + // we've captured all bytes in frame. tell the next section we're ready to write + // the frame into wireshark + if (byte_ctr == (len - 1)) + { + state = FSM.START_CAPTURE; + file_write = true; + } + break; + } + } + + // at least one frame has been captured. write it into wireshark + while (file_write == true) + { + frame_len = b[rd_idx]; + bytes_in_buf = calc_bytes_in_buf(); + + // compare the frame lengto the number of bytes in the buffer. if the bytes in buffer are + // greater than the frame length, then we have more than one frame. loop through until + // all complete frames have been written to wireshark + if (bytes_in_buf > frame_len) + { + // more than one frame in buffer. don't indicate we're finished yet in case we have + // other frames we can send out. + write_frame(frame_len); + } + else if (bytes_in_buf == frame_len) + { + // only one frame in buffer. indicate we're finished after we write this frame out. + write_frame(frame_len); + file_write = false; + } + else + { + // what?! no frames in buffer? we shouldn't reach here. + file_write = false; + } + } + } + + // return the number of bytes in the buffer + static uint calc_bytes_in_buf() + { + if (rd_idx > wr_idx) + { + // since we're using a circular buffer, its possible for the write index to be less + // than the read index if a wraparound occurred. handle this case here. + return (BUFSIZE - (rd_idx - wr_idx)); + } + else + { + // normal way to calculate bytes in the buffer + return (wr_idx - rd_idx); + } + } + + // this is the global header that starts any packet capture file. this will tell wireshark what + // kind of protocol it is (indicated by the DLT) as well as other information like endianness, etc. + static void write_global_hdr() + { + uint magic_num = 0xa1b2c3d4; // used for endianness + short version_major = 2; // version + short version_minor = 4; // version + int thiszone = 0; // zone (unused) + uint sigfigs = 0; // significant figures (unused) + uint snaplen = 65535; // snapshot length (max value) + uint network = 195; // Data Link Type (DLT): indicates link layer protocol + + try + { + // write to wireshark pipe + ws.Write(magic_num); + ws.Write(version_major); + ws.Write(version_minor); + ws.Write(thiszone); + ws.Write(sigfigs); + ws.Write(snaplen); + ws.Write(network); + } + catch + { + Console.WriteLine("Pipe has been closed."); + close(); + } + } + + // this writes a frame header into wireshark in libpcap format. the format is simple and just + // requires a timestamp and length + static void write_frm_hdr(long sec, long usec, uint incl_len, uint orig_len) + { + try + { + // write to wireshark + ws.Write((uint)sec); + ws.Write((uint)usec); + ws.Write(incl_len); + ws.Write(orig_len); + } + catch + { + Console.WriteLine("Pipe has been closed."); + close(); + } + } + + // this writes a frame into wireshark. it calculates the timestamp and length and uses that + // for the frame header. it then writes captured bytes into wireshark + static void write_frame(uint frame_len) + { + uint incl_len, orig_len; + long sec, usec; + + // generating timestamp. its kind of cheesy but there isn't a unix timestamp mechanism in win. + // just counting ticks from when program was started. each tick is 100 nsec. + long diff_in_ticks = DateTime.Now.Ticks - start_time_in_ticks; // get difference in ticks + sec = diff_in_ticks / TimeSpan.TicksPerSecond; // get seconds + diff_in_ticks -= (sec * TimeSpan.TicksPerSecond); // subtract off seconds from total + usec = diff_in_ticks / 10; // get usec + + // calculate frame length. we won't be feeding frame checksum (FCS) into wireshark. + incl_len = (uint)frame_len - PACKET_FCS; + orig_len = frame_len; + + // increment over the length byte. we won't feed that into wireshark either. it doesn't seem to like it. + rd_idx = (rd_idx + 1) % BUFSIZE; + + // write frame header first + write_frm_hdr(sec, usec, incl_len, orig_len); + + // loop through entire length and write data into wireshark + for (int i = 0; i < incl_len; i++) + { + try + { + ws.Write(b[rd_idx]); + } + catch + { + Console.WriteLine("Pipe has been closed."); + close(); + } + rd_idx = (rd_idx + 1) % BUFSIZE; + } + rd_idx = (rd_idx + 1) % BUFSIZE; + } + + // Received some type of termination. Close everything and wrap up. + static void close() + { + p.Close(); + wspipe.Close(); + ws.Close(); + Console.WriteLine("Press key to quit."); + Console.ReadLine(); + Environment.Exit(0); + } + } +} diff --git a/tools/wsbridge/v0.50/Win/wsbridge/Properties/AssemblyInfo.cs b/tools/wsbridge/v0.50/Win/wsbridge/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cca8ed9 --- /dev/null +++ b/tools/wsbridge/v0.50/Win/wsbridge/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("pcap")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("pcap")] +[assembly: AssemblyCopyright("Copyright © 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("75eb0967-9c50-430e-a562-d0f7bee8f2cc")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj b/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj new file mode 100644 index 0000000..be4b179 --- /dev/null +++ b/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj @@ -0,0 +1,96 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {9CAFA529-8FF4-42D4-B6A6-54992B3BB40F} + Exe + Properties + wsbridge + wsbridge + v3.5 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + False + .NET Framework 2.0 %28x86%29 + false + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj.user b/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj.user new file mode 100644 index 0000000..191b576 --- /dev/null +++ b/tools/wsbridge/v0.50/Win/wsbridge/wsbridge.csproj.user @@ -0,0 +1,15 @@ + + + publish\ + + + + + + + + + en-US + false + + \ No newline at end of file