From: Miceuz Date: Tue, 29 May 2012 21:32:39 +0000 (+0200) Subject: Merge branch 'master' of git://github.com/microbuilder/LPC1343CodeBase X-Git-Url: http://git.rohieb.name/hackover2013-badge-firmware.git/commitdiff_plain/9b1c307f5be2e264cf0ce6f38af872f2b149be5d?hp=792119439b0f68cb94bc6300623a4020cb37f124 Merge branch 'master' of git://github.com/microbuilder/LPC1343CodeBase --- diff --git a/ChangeLog.txt b/ChangeLog.txt index e083124..830c427 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -2,7 +2,12 @@ v1.1.2 - ongoing ============================================================================== NEW FEATURES ------------------------------------------------------------------------------ +- Added drivers/sensors/ina219/ina219.c (work in progress!) +- Added drivers/displays/tft/hw/hx8347d.C (courtesy tauonteilchen again) +- Added drivers/dac/mcp4901 (courtesy tauonteilchen, thanks!) +- Cleaned up /tools/testfirmware to include more recent blinky, etc. - Added basic TEA5767 drive +- Added core/cmd/ansi.h (rediscover the joy of ANSI graphics codes :) - Added fastHLine and fastVLine to lcdProperties_t for all lcd drivers (to known whether an accelerated vertical or horizontal line drawing function is present in the driver or not) @@ -10,6 +15,11 @@ NEW FEATURES - Added PWM command to CLI (thanks Miceuz) - Added optional callback in 32-bit timer ISR (thanks again Miceuz) +BUG FIXES/OPTIMISATIONS/ETC. +------------------------------------------------------------------------------ +- Minor accuracy improvement to pwm.c (off by 1 error) +- Fixed typos in cmd_pwm.c and cmd_tbl.h +- Changed I2C default speed to 400kHz (from 100kHz) v1.1.1 - 14 April 2012 ============================================================================== diff --git a/Makefile b/Makefile index 482caea..a3aa928 100644 --- a/Makefile +++ b/Makefile @@ -1,239 +1,244 @@ -########################################################################## -# 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 - -########################################################################## -# Debug settings -########################################################################## - -# Set DEBUGBUILD to 'TRUE' for full debugging (larger, slower binaries), -# or to 'FALSE' for release builds (smallest, fastest binaries) -DEBUGBUILD = FALSE - -########################################################################## -# IDE Flags (Keeps various IDEs happy) -########################################################################## - -OPTDEFINES = -D __NEWLIB__ - -########################################################################## -# Project-specific files -########################################################################## - -VPATH += project -OBJS += commands.o - -VPATH += project/commands -OBJS += cmd_chibi_addr.o cmd_chibi_tx.o -OBJS += cmd_i2ceeprom_read.o cmd_i2ceeprom_write.o cmd_lm75b_gettemp.o -OBJS += cmd_reset.o cmd_sd_dir.o cmd_sysinfo.o cmd_uart.o -OBJS += cmd_roundedcorner.o cmd_pwm.o - -VPATH += project/commands/drawing -OBJS += cmd_backlight.o cmd_bmp.o cmd_button.o cmd_calibrate.o -OBJS += cmd_circle.o cmd_clear.o cmd_line.o cmd_orientation.o -OBJS += cmd_pixel.o cmd_progress.o cmd_rectangle.o cmd_text.o -OBJS += cmd_textw.o cmd_tsthreshhold.o cmd_tswait.o cmd_triangle.o - -########################################################################## -# Optional driver files -########################################################################## - -# Chibi Light-Weight Wireless Stack (AT86RF212) -VPATH += drivers/rf/chibi -OBJS += chb.o chb_buf.o chb_drvr.o chb_eeprom.o chb_spi.o - -# 4K EEPROM -VPATH += drivers/storage/eeprom drivers/storage/eeprom/mcp24aa -OBJS += eeprom.o mcp24aa.o - -# LM75B temperature sensor -VPATH += drivers/sensors/lm75b -OBJS += lm75b.o - -# ISL12022M RTC -VPATH += drivers/rtc/isl12022m -OBJS += isl12022m.o - -# TFT LCD support -VPATH += drivers/displays/tft drivers/displays/tft/hw -OBJS += drawing.o touchscreen.o colors.o theme.o bmp.o - -# GUI Controls -VPATH += drivers/displays/tft/controls -OBJS += button.o hsbchart.o huechart.o label.o -OBJS += labelcentered.o progressbar.o - -# Bitmap (non-AA) fonts -VPATH += drivers/displays/tft/fonts -OBJS += fonts.o -OBJS += dejavusans9.o dejavusansbold9.o dejavusanscondensed9.o -OBJS += dejavusansmono8.o dejavusansmonobold8.o -OBJS += verdana9.o verdana14.o verdanabold14.o - -# Anti-aliased fonts -VPATH += drivers/displays/tft/aafonts/aa2 drivers/displays/tft/aafonts/aa4 -OBJS += aafonts.o -OBJS += DejaVuSansCondensed14_AA2.o DejaVuSansCondensedBold14_AA2.o -OBJS += DejaVuSansMono10_AA2.o DejaVuSansMono13_AA2.o DejaVuSansMono14_AA2.o - -# LCD Driver (Only one can be included at a time!) -# OBJS += hx8340b.o -OBJS += ILI9328.o -# OBJS += ILI9325.o -# OBJS += ssd1331.o -# OBJS += ssd1351.o -# OBJS += st7735.o -# OBJS += st7783.o - -# Bitmap/Monochrome LCD support (ST7565, SSD1306, etc.) -VPATH += drivers/displays -VPATH += drivers/displays/bitmap/sharpmem -VPATH += drivers/displays/bitmap/st7565 -VPATH += drivers/displays/bitmap/ssd1306 -OBJS += smallfonts.o sharpmem.o st7565.o ssd1306.o - -#Character Displays (VFD text displays, etc.) -VPATH += drivers/displays/character/samsung_20T202DA2JA -OBJS += samsung_20T202DA2JA.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/rf/pn532 drivers/rf/pn532/helpers -OBJS += pn532.o pn532_bus_i2c.o pn532_bus_uart.o -OBJS += pn532_mifare_classic.o pn532_mifare_ultralight.o - -# TAOS Light Sensors -VPATH += drivers/sensors/tcs3414 drivers/sensors/tsl2561 -OBJS += tcs3414.o tsl2561.o - -# SPI Flash -VPATH += drivers/storage/spiflash/w25q16bv -OBJS += w25q16bv.o - -# FM Radio -VPATH += drivers/audio/tea5767 -OBJS += tea5767.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/wdt core/usbcdc core/pwm core/iap -VPATH += core/libc -OBJS += stdio.o string.o -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 -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 -########################################################################## -ifeq (TRUE,$(DEBUGBUILD)) - CFLAGS = -c -g -O0 $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin $(OPTDEFINES) - ASFLAGS = -c -g -O0 $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -D__ASSEMBLY__ -x assembler-with-cpp -else - CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin $(OPTDEFINES) - ASFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -D__ASSEMBLY__ -x assembler-with-cpp -endif - -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 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 +########################################################################## +# 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 + +########################################################################## +# Debug settings +########################################################################## + +# Set DEBUGBUILD to 'TRUE' for full debugging (larger, slower binaries), +# or to 'FALSE' for release builds (smallest, fastest binaries) +DEBUGBUILD = FALSE + +########################################################################## +# IDE Flags (Keeps various IDEs happy) +########################################################################## + +OPTDEFINES = -D __NEWLIB__ + +########################################################################## +# Project-specific files +########################################################################## + +VPATH += project +OBJS += commands.o + +VPATH += project/commands +OBJS += cmd_chibi_addr.o cmd_chibi_tx.o +OBJS += cmd_i2ceeprom_read.o cmd_i2ceeprom_write.o cmd_lm75b_gettemp.o +OBJS += cmd_reset.o cmd_sd_dir.o cmd_sysinfo.o cmd_uart.o +OBJS += cmd_roundedcorner.o cmd_pwm.o + +VPATH += project/commands/drawing +OBJS += cmd_backlight.o cmd_bmp.o cmd_button.o cmd_calibrate.o +OBJS += cmd_circle.o cmd_clear.o cmd_line.o cmd_orientation.o +OBJS += cmd_pixel.o cmd_progress.o cmd_rectangle.o cmd_text.o +OBJS += cmd_textw.o cmd_tsthreshhold.o cmd_tswait.o cmd_triangle.o + +########################################################################## +# Optional driver files +########################################################################## + +# Chibi Light-Weight Wireless Stack (AT86RF212) +VPATH += drivers/rf/chibi +OBJS += chb.o chb_buf.o chb_drvr.o chb_eeprom.o chb_spi.o + +# 4K EEPROM +VPATH += drivers/storage/eeprom drivers/storage/eeprom/mcp24aa +OBJS += eeprom.o mcp24aa.o + +# LM75B temperature sensor +VPATH += drivers/sensors/lm75b +OBJS += lm75b.o + +# ISL12022M RTC +VPATH += drivers/rtc/isl12022m +OBJS += isl12022m.o + +# TFT LCD support +VPATH += drivers/displays/tft drivers/displays/tft/hw +OBJS += drawing.o touchscreen.o colors.o theme.o bmp.o + +# GUI Controls +VPATH += drivers/displays/tft/controls +OBJS += button.o hsbchart.o huechart.o label.o +OBJS += labelcentered.o progressbar.o + +# Bitmap (non-AA) fonts +VPATH += drivers/displays/tft/fonts +OBJS += fonts.o +OBJS += dejavusans9.o dejavusansbold9.o dejavusanscondensed9.o +OBJS += dejavusansmono8.o dejavusansmonobold8.o +OBJS += verdana9.o verdana14.o verdanabold14.o + +# Anti-aliased fonts +VPATH += drivers/displays/tft/aafonts/aa2 drivers/displays/tft/aafonts/aa4 +OBJS += aafonts.o +OBJS += DejaVuSansCondensed14_AA2.o DejaVuSansCondensedBold14_AA2.o +OBJS += DejaVuSansMono10_AA2.o DejaVuSansMono13_AA2.o DejaVuSansMono14_AA2.o + +# LCD Driver (Only one can be included at a time!) +# OBJS += hx8340b.o +# OBJS += hx8347d.o +OBJS += ILI9328.o +# OBJS += ILI9325.o +# OBJS += ssd1331.o +# OBJS += ssd1351.o +# OBJS += st7735.o +# OBJS += st7783.o + +# Bitmap/Monochrome LCD support (ST7565, SSD1306, etc.) +VPATH += drivers/displays +VPATH += drivers/displays/bitmap/sharpmem +VPATH += drivers/displays/bitmap/st7565 +VPATH += drivers/displays/bitmap/ssd1306 +OBJS += smallfonts.o sharpmem.o st7565.o ssd1306.o + +#Character Displays (VFD text displays, etc.) +VPATH += drivers/displays/character/samsung_20T202DA2JA +OBJS += samsung_20T202DA2JA.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 drivers/dac/mcp4901 +OBJS += mcp4725.o mcp4901.o + +# RFID/NFC +VPATH += drivers/rf/pn532 drivers/rf/pn532/helpers +OBJS += pn532.o pn532_bus_i2c.o pn532_bus_uart.o +OBJS += pn532_mifare_classic.o pn532_mifare_ultralight.o + +# TAOS Light Sensors +VPATH += drivers/sensors/tcs3414 drivers/sensors/tsl2561 +OBJS += tcs3414.o tsl2561.o + +# SPI Flash +VPATH += drivers/storage/spiflash/w25q16bv +OBJS += w25q16bv.o + +# FM Radio +VPATH += drivers/audio/tea5767 +OBJS += tea5767.o + +# IN219 Current Sensor +VPATH += drivers/sensors/ina219 +OBJS += ina219.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/wdt core/usbcdc core/pwm core/iap +VPATH += core/libc +OBJS += stdio.o string.o +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 +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 +########################################################################## +ifeq (TRUE,$(DEBUGBUILD)) + CFLAGS = -c -g -O0 $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin $(OPTDEFINES) + ASFLAGS = -c -g -O0 $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -D__ASSEMBLY__ -x assembler-with-cpp +else + CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin $(OPTDEFINES) + ASFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -D__ASSEMBLY__ -x assembler-with-cpp +endif + +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 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/build/codelite/LPC1343 Workspace.workspace.session b/build/codelite/LPC1343 Workspace.workspace.session index b59e362..c047e00 100644 --- a/build/codelite/LPC1343 Workspace.workspace.session +++ b/build/codelite/LPC1343 Workspace.workspace.session @@ -17,13 +17,19 @@ - - + + + + + + + + - + @@ -40,5 +46,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/codelite/LPC1343_CodeBase.project b/build/codelite/LPC1343_CodeBase.project index 10d1983..d2b88b4 100644 --- a/build/codelite/LPC1343_CodeBase.project +++ b/build/codelite/LPC1343_CodeBase.project @@ -370,7 +370,7 @@ - + @@ -380,7 +380,7 @@ - + # Make sure that we are using SWD monitor interface SWD diff --git a/build/crossworks/LPC1343_CodeBase.hzp b/build/crossworks/LPC1343_CodeBase.hzp index 49398d9..636619f 100644 --- a/build/crossworks/LPC1343_CodeBase.hzp +++ b/build/crossworks/LPC1343_CodeBase.hzp @@ -73,6 +73,7 @@ + @@ -122,6 +123,9 @@ + + + @@ -167,6 +171,10 @@ + + + + @@ -273,6 +281,9 @@ + + + diff --git a/build/crossworks/LPC1343_CodeBase.hzs b/build/crossworks/LPC1343_CodeBase.hzs index d03e981..61c5d6a 100644 --- a/build/crossworks/LPC1343_CodeBase.hzs +++ b/build/crossworks/LPC1343_CodeBase.hzs @@ -24,7 +24,9 @@ - + + + @@ -44,10 +46,10 @@ - - - + + + @@ -60,7 +62,14 @@ - + + + + + + + + - + diff --git a/core/adc/adc.c b/core/adc/adc.c index 5728545..0a6dd39 100644 --- a/core/adc/adc.c +++ b/core/adc/adc.c @@ -162,6 +162,48 @@ uint32_t adcReadSingle (uint8_t channelNum) return (adcData); } +/**************************************************************************/ +/*! + @brief Returns the oversampled conversion results on the specified ADC channel. + + This function will manually start A/D conversions on a single + channel sum and divide results to get a value of increased resolution. + + Read more: AVR121: Enhancing ADC resolution by oversampling [http://www.atmel.com/Images/doc8003.pdf] + + @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.) + + @param[in] extraBits + Additional bits you want to add to resolution. Hardware resolution is + 10bits, if 6 is psecified as extraBits, the resolution will be increated to + 16 bit. + + @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 adcReadOversampled (uint8_t channelNum, uint8_t extraBits) { + uint32_t sampleCount = 1 << (extraBits * 2); + uint16_t i; + uint32_t adcOversampled = 0; + + for(i = 0; i < sampleCount; i++) { + uint16_t adcValue = adcReadSingle(channelNum); + adcOversampled += adcValue; + } + + adcOversampled = adcOversampled >> extraBits; + return adcOversampled; +} + /**************************************************************************/ /*! @brief Returns the conversion results on the specified ADC channel. diff --git a/core/adc/adc.h b/core/adc/adc.h index 29e168d..a1c3879 100644 --- a/core/adc/adc.h +++ b/core/adc/adc.h @@ -42,6 +42,8 @@ #include "projectconfig.h" uint32_t adcRead (uint8_t channelNum); -void adcInit (void); +uint32_t adcReadOversampled (uint8_t channelNum, uint8_t extraBits); +uint32_t adcReadSingle(uint8_t channelNum); +void adcInit (void); #endif diff --git a/core/i2c/i2c.h b/core/i2c/i2c.h index 5e16c82..bdf5b70 100644 --- a/core/i2c/i2c.h +++ b/core/i2c/i2c.h @@ -89,8 +89,8 @@ Fast Mode (400KHz) = CFG_CPU_CCLK / 800000 Fast- Mode Plus (1MHz) = CFG_CPU_CCLK / 2000000 */ -#define I2SCLH_SCLH CFG_CPU_CCLK / 200000 /* Standard Mode I2C SCL Duty Cycle High (400KHz) */ -#define I2SCLL_SCLL CFG_CPU_CCLK / 200000 /* Fast Mode I2C SCL Duty Cycle Low (400KHz) */ +#define I2SCLH_SCLH CFG_CPU_CCLK / 800000 /* Standard Mode I2C SCL Duty Cycle High (400KHz) */ +#define I2SCLL_SCLL CFG_CPU_CCLK / 800000 /* Fast Mode I2C SCL Duty Cycle Low (400KHz) */ #define I2SCLH_HS_SCLH CFG_CPU_CCLK / 2000000 /* Fast Plus I2C SCL Duty Cycle High Reg */ #define I2SCLL_HS_SCLL CFG_CPU_CCLK / 2000000 /* Fast Plus I2C SCL Duty Cycle Low Reg */ diff --git a/core/pwm/pwm.c b/core/pwm/pwm.c index 7f1e2e5..a27b666 100644 --- a/core/pwm/pwm.c +++ b/core/pwm/pwm.c @@ -178,7 +178,7 @@ int pwmSetDutyCycle(uint32_t percentage) } /* Set Duty Cycle (MR0) */ - TMR_TMR16B1MR0 = ((pwmPulseWidth * (100 - (pwmDutyCycle = percentage))) / 100) + 1; + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - (pwmDutyCycle = percentage))) / 100; return 0; } @@ -246,7 +246,7 @@ int pwmSetFrequencyInMicroseconds(uint16_t us) TMR_TMR16B1MR3 = (pwmPulseWidth = ticks - 1); /* Adjust Duty Cycle (MR0) */ - TMR_TMR16B1MR0 = ((pwmPulseWidth * (100 - pwmDutyCycle)) / 100) + 1; + TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100; return 0; } diff --git a/drivers/dac/mcp4725/mcp4725.h b/drivers/dac/mcp4725/mcp4725.h index 71100cc..bb91b3e 100644 --- a/drivers/dac/mcp4725/mcp4725.h +++ b/drivers/dac/mcp4725/mcp4725.h @@ -39,7 +39,8 @@ #include "projectconfig.h" -#define MCP4725_ADDRESS (0xC0) // 1100000x - Assumes A0 is GND and A2,A1 are 0 (MCP4725A0T-E/CH) +//#define MCP4725_ADDRESS (0xC0) // 1100000x - Assumes A0 is GND and A2,A1 are 00 (MCP4725A0T-E/CH) +#define MCP4725_ADDRESS (0xC4) // 1100010x - Assumes A0 is GND and A2,A1 are 01 (MCP4725A1T-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) diff --git a/drivers/dac/mcp4901/mcp4901.c b/drivers/dac/mcp4901/mcp4901.c new file mode 100644 index 0000000..faed8bd --- /dev/null +++ b/drivers/dac/mcp4901/mcp4901.c @@ -0,0 +1,127 @@ +/**************************************************************************/ +/*! + @file mcp4901.c + @author Tauon + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012, Tauon + 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 "mcp4901.h" + +#define DAC_BUF 0 +#define DAC_GA 1 +#define DAC_SHDN 1 +#define DAC_BITS8 + +uint16_t settings; + +// Control pins +#define MCP4901_GPIODATAREG (*(pREG32 (0x50023FFC))) // GPIO2DATA +#define MCP4901_PORT (2) + +#define MCP4901_LDAC (0) +#define MCP4901_CS_PIN (6) +#define MCP4901_SCL_PIN (7) +#define MCP4901_SDI_PIN (8) + +// Macros for control line state +#define CLR_SDI do { MCP4901_GPIODATAREG &= ~(1<>8) & 0xFF); + mcpWriteData(data & 0xFF); +} + +void mcp4901Init() +{ + settings = (DAC_BUF << 2 | DAC_GA << 1 | DAC_SHDN) << 12; + gpioSetDir(MCP4901_PORT, MCP4901_LDAC , gpioDirection_Output); + gpioSetDir(MCP4901_PORT, MCP4901_CS_PIN , gpioDirection_Output); + gpioSetDir(MCP4901_PORT, MCP4901_SCL_PIN, gpioDirection_Output); + gpioSetDir(MCP4901_PORT, MCP4901_SDI_PIN, gpioDirection_Output); +} +void mcp4901ChangeSettings(bool BUFFER, bool GAIN, bool SHUTDOWN) +{ + settings = (BUFFER << 2 | GAIN << 1 | (!SHUTDOWN)) << 12; +} +void mcp4901LDAC(void) +{ + gpioSetValue(MCP4901_PORT,MCP4901_LDAC,0); + gpioSetValue(MCP4901_PORT,MCP4901_LDAC,1); +} +void mcp4901SetVoltage( uint8_t output) +{ + uint16_t data; + #ifdef DAC_BITS8 + data = settings | (output << 4); + #endif + + #ifdef DAC_BITS10 + data = settings | (output << 2); + #endif + + #ifdef DAC_BITS12 + data = settings | output; + #endif + CLR_CS; + mcpWriteData16(data); + SET_CS; +} + + diff --git a/drivers/dac/mcp4901/mcp4901.h b/drivers/dac/mcp4901/mcp4901.h new file mode 100644 index 0000000..930e3bf --- /dev/null +++ b/drivers/dac/mcp4901/mcp4901.h @@ -0,0 +1,48 @@ +/**************************************************************************/ +/*! + @file mcp4901.h + @author Tauon + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012, Tauon + 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 _MCP4901_H_ +#define _MCP4901_H_ + +#include "projectconfig.h" +#include "core/gpio/gpio.h" + +void mcp4901Init(void); +void mcp4901SetVoltage( uint8_t output); +void mcp4901LDAC(void); +void mcp4901ChangeSettings(bool BUFFER, bool GAIN, bool SHUTDOWN); + +#endif diff --git a/drivers/displays/tft/controls/button.c b/drivers/displays/tft/controls/button.c index db29382..c657823 100644 --- a/drivers/displays/tft/controls/button.c +++ b/drivers/displays/tft/controls/button.c @@ -59,9 +59,6 @@ /**************************************************************************/ void buttonRender(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t fontColor, char *text, theme_t theme) { - uint16_t brighter, darker; - uint16_t buttonEnd; - // Draw background gradient then outline drawGradient(x+2, y+2, x+width-2, y+height-2, theme.colorFill, theme.colorBorder); drawRoundedRectangle(x+1, y+1, x+width-1, y+height-1, theme.colorFill, 5, DRAW_CORNERS_ALL); diff --git a/drivers/displays/tft/hw/hx8347d.c b/drivers/displays/tft/hw/hx8347d.c new file mode 100644 index 0000000..dd115f6 --- /dev/null +++ b/drivers/displays/tft/hw/hx8347d.c @@ -0,0 +1,703 @@ +/**************************************************************************/ +/*! + @file hx8347d.c + @author Tauon {TauonTeilchen} Jabber ID Tauon[at]jabber.ccc.de + + @section DESCRIPTION + Driver for hx8347h 240x320 pixel TFT LCD displays. + Is written for MI0283QT-2 LCD from watterott.com + More infos: http://www.watterott.com/de/MI0283QT-2-Adapter + http://www.watterott.com/index.php?page=product&info=1597&dl_media=3202 + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012, TauonTeilchen + ---------------------------------------------------------------------------- + "THE ClubMate-WARE LICENSE" (Revision 42): + JID: wrote this file. As long as you retain this notice you + can do whatever you want with this stuff. If we meet some day, and you think + this stuff is worth it, you can buy me a ClubMate in return Tauon + ---------------------------------------------------------------------------- + ---------------------------------------------------------------------------- + "THE ClubMate-WARE LICENSE" (Revision 42): + JID: schrieb diese Datei. Solange Sie diesen Vermerk nicht entfernen, k�nnen + Sie mit dem Material machen, was Sie m�chten. Wenn wir uns eines Tages treffen und Sie + denken, das Material ist es wert, k�nnen Sie mir daf�r ein ClubMate ausgeben. Tauon + ---------------------------------------------------------------------------- + +*/ +/**************************************************************************/ +#include "drivers/displays/tft/hw/hx8347d.h" + +#define LCD_ID (0x00) +#define LCD_DATA ((0x72)|(LCD_ID<<2)) +#define LCD_REGISTER ((0x70)|(LCD_ID<<2)) + +#define LCD_BACK_LIGHT 6 +#define LCD_RST 5 +#define LCD_CS 4 + +// Macros for control line state +#define LCD_CS_ENABLE() GPIO_GPIO2DATA &= ~0x10 // gpioSetValue(2, 4, 0) +#define LCD_CS_DISABLE() GPIO_GPIO2DATA |= 0x10 // gpioSetValue(2, 4, 1) +#define LCD_RST_ENABLE() GPIO_GPIO2DATA &= ~0x20 // gpioSetValue(2, 5, 0) +#define LCD_RST_DISABLE() GPIO_GPIO2DATA |= 0x20 // gpioSetValue(2, 5, 1) + +#define Himax ID 0x00 +#define Display_Mode_Control 0x01 + +#define Column_Address_Start_2 0x02 +#define Column_Address_Start_1 0x03 +#define Column_Address_End_2 0x04 +#define Column_Address_End_1 0x05 + +#define Row_Address_Start_2 0x06 +#define Row_Address_Start_1 0x07 +#define Row_Address_End_2 0x08 +#define Row_Address_End_1 0x09 + +#define Partial_Area_Start_Row_2 0x0A +#define Partial_Area_Start_Row_1 0x0B +#define Partial_Area_End_Row_2 0x0C +#define Partial_Area_End_Row_1 0x0D + +#define TFA_REGISTER 0x0E +#define VSA_REGISTER 0x10 +#define BFA_REGISTER 0x12 +#define VSP_REGISTER 0x14 + +#define COLMOD 0x17 +#define OSC_Control_1 0x18 +#define OSC_Control_2 0x19 +#define Power_Control_1 0x1A +#define Power_Control_2 0x1B +#define Power_Control_3 0x1C +#define Power_Control_4 0x1D +#define Power_Control_5 0x1E +#define Power_Control_6 0x1F +#define VCOM_Control_1 0x23 +#define VCOM_Control_2 0x24 +#define VCOM_Control_3 0x25 +#define Display_Control_1 0x26 +#define Display_Control_2 0x27 +#define Display_Control_3 0x28 +#define Source_OP_Control_Normal 0xE8 +#define Source_OP_Control_IDLE 0xE9 +#define Power_Control_Internal_1 0xEA +#define Power_Control_Internal_2 0xEB +#define Source_Control_Internal_1 0xEC +#define Source_Control_Internal_2 0xED + +#define OSC_Control_2_OSC_EN 0x01 +#define Display_Control_3_GON 0x20 +#define Display_Control_3_DTE 0x10 +#define Display_Control_3_D0 0x04 +#define Display_Control_3_D1 0x08 +#define Power_Control_6_STB 0x01 +#define Display_Mode_Control_DP_STB_S 0x40 +#define Display_Mode_Control_DP_STB 0x80 + +uint16_t offset; + +/*************************************************/ +/* Private Methods */ +/*************************************************/ +void lcd_drawstart(void); +void lcd_cmd(uint16_t reg, uint16_t param); +void lcd_clear(uint16_t color); +void lcd_draw(uint16_t color); +void lcd_drawstart(void); +void lcd_drawstop(void); +void hx8347d_DisplayOnFlow(void); +void hx8347d_DisplayOffFlow(void); +void lcd_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + + +void hx8347d_Scroll(uint16_t tfa,uint16_t vsa,uint16_t bfa, uint16_t vsp) +{ + lcd_cmd(TFA_REGISTER , tfa >> 8); + lcd_cmd(TFA_REGISTER + 1, tfa & 0xFF); + + lcd_cmd(VSA_REGISTER , vsa >> 8); + lcd_cmd(VSA_REGISTER + 1, vsa & 0xFF); + + lcd_cmd(BFA_REGISTER , bfa >> 8); + lcd_cmd(BFA_REGISTER + 1, bfa & 0xFF); + + lcd_cmd(VSP_REGISTER , vsp>> 8); + lcd_cmd(VSP_REGISTER + 1, vsp & 0xFF); + lcd_cmd(0x01, 0x08); //scroll on +} + +void displayOnFlow(void) +{ + lcd_cmd(Display_Control_3, 0x0038); + systickDelay(4); + lcd_cmd(Display_Control_3, 0x003C); +} +void displayOffFlow(void) +{ + lcd_cmd(Display_Control_3, Display_Control_3_GON | Display_Control_3_DTE | Display_Control_3_D1); + systickDelay(4); + lcd_cmd(Display_Control_3, Display_Control_3_D0); +} + +void lcd_cmd(uint16_t reg, uint16_t param) +{ + uint8_t b_first[2]; + uint8_t b_sec[2]; + LCD_CS_ENABLE(); + + b_first[0] = LCD_REGISTER; + b_first[1] = reg; + + sspSend(0, b_first, 2); + LCD_CS_DISABLE(); + + b_sec[0] = LCD_DATA; + b_sec[1] = param; + LCD_CS_ENABLE(); + + sspSend(0, b_sec, 2); + LCD_CS_DISABLE(); + + return; +} + +void lcd_clear(uint16_t color) +{ + unsigned int i; + + lcd_area(0, 0, (hx8347dProperties.width -1), (hx8347dProperties.height-1)); + + lcd_drawstart(); + for(i=(hx8347dProperties.width*hx8347dProperties.height/8); i!=0; i--) + { + lcd_draw(color); //1 + lcd_draw(color); //2 + lcd_draw(color); //3 + lcd_draw(color); //4 + lcd_draw(color); //5 + lcd_draw(color); //6 + lcd_draw(color); //7 + lcd_draw(color); //8 + } + lcd_drawstop(); + + return; +} + +void lcd_draw(uint16_t color) +{ + // Writing data in 16Bit mode for saving a lot of time + /* 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 = color; + + 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. */ + uint8_t Dummy = SSP_SSP0DR; + return; +} + +void lcd_drawstop(void) +{ + while ((SSP_SSP0SR & SSP_SSP0SR_TFE_MASK ) != SSP_SSP0SR_TFE_EMPTY ); + LCD_CS_DISABLE(); + + // init 8Bit SPI Mode + SSP_SSP0CR0 &= ~SSP_SSP0CR0_DSS_MASK; + SSP_SSP0CR0 |= SSP_SSP0CR0_DSS_8BIT; + + return; +} + +void lcd_drawstart(void) +{ + LCD_CS_ENABLE(); + uint8_t b_first[2]; + uint8_t b_sec[1]; + b_first[0] = LCD_REGISTER; + b_first[1] = 0x22; + sspSend(0, b_first, 2); + LCD_CS_DISABLE(); + + LCD_CS_ENABLE(); + b_sec[0] = LCD_DATA; + sspSend(0, b_sec, 1); + + + // Assign config values to SSP0CR0 + // init 16Bit SPI Mode for fast data transmitting + SSP_SSP0CR0 &= ~SSP_SSP0CR0_DSS_MASK; + SSP_SSP0CR0 |= SSP_SSP0CR0_DSS_16BIT; + + return; +} + +void lcd_area(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + if(hx8347dPOrientation == LCD_ORIENTATION_PORTRAIT) + { + y0 = ((320-offset)+ y0) % 320; + y1 = ((320-offset)+ y1) % 320; + } + else + { + x0 = ((320-offset)+ x0) % 320; + x1 = ((320-offset)+ x1) % 320; + } + lcd_cmd(Column_Address_Start_1, (x0>>0)); //set x0 + lcd_cmd(Column_Address_Start_2, (x0>>8)); //set x0 + lcd_cmd(Column_Address_End_1 , (x1>>0)); //set x1 + lcd_cmd(Column_Address_End_2 , (x1>>8)); //set x1 + lcd_cmd(Row_Address_Start_1 , (y0>>0)); //set y0 + lcd_cmd(Row_Address_Start_2 , (y0>>8)); //set y0 + lcd_cmd(Row_Address_End_1 , (y1>>0)); //set y1 + lcd_cmd(Row_Address_End_2 , (y1>>8)); //set y1 + + return; +} + +void lcd_cursor(uint16_t x, uint16_t y) +{ + lcd_area(x, y, x, y); + return; +} + +void lcd_data(uint16_t c) +{ + LCD_CS_ENABLE(); + uint8_t b[3]; + b[0] = LCD_DATA; + b[1] = c>>8; + b[2] = c; + sspSend(0, b, 3); + + LCD_CS_DISABLE(); + + return; +} + +void fillRect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) +{ + uint32_t size; + uint16_t tmp, i; + + if(x0 > x1) + { + tmp = x0; + x0 = x1; + x1 = tmp; + } + if(y0 > y1) + { + tmp = y0; + y0 = y1; + y1 = tmp; + } + + if(x1 >= hx8347dProperties.width) + { + x1 = hx8347dProperties.width-1; + } + if(y1 >= hx8347dProperties.height) + { + y1 = hx8347dProperties.height-1; + } + + lcd_area(x0, y0, x1, y1); + + lcd_drawstart(); + size = (uint32_t)(1+(x1-x0)) * (uint32_t)(1+(y1-y0)); + tmp = size/8; + if(tmp != 0) + { + for(i=tmp; i!=0; i--) + { + lcd_draw(color); //1 + lcd_draw(color); //2 + lcd_draw(color); //3 + lcd_draw(color); //4 + lcd_draw(color); //5 + lcd_draw(color); //6 + lcd_draw(color); //7 + lcd_draw(color); //8 + } + for(i=size-tmp; i!=0; i--) + { + lcd_draw(color); + } + } + else + { + for(i=size; i!=0; i--) + { + lcd_draw(color); + } + } + lcd_drawstop(); + + return; +} + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +/**************************************************************************/ +/*! + @brief Configures any pins or HW and initialises the LCD controller +*/ +/**************************************************************************/ +void lcdInit(void) +{ + sspInit(0,0,0); + + gpioSetDir(2, LCD_CS, gpioDirection_Output); + gpioSetDir(2, LCD_RST, gpioDirection_Output); + gpioSetDir(2, LCD_BACK_LIGHT, gpioDirection_Output); + + //reset + LCD_CS_DISABLE(); + systickDelay(1); + LCD_RST_ENABLE(); + systickDelay(50); + LCD_RST_DISABLE(); + systickDelay(50); + + //driving ability + lcd_cmd(Power_Control_Internal_1 , 0x0000); + lcd_cmd(Power_Control_Internal_2 , 0x0020); + lcd_cmd(Source_Control_Internal_1, 0x000C); + lcd_cmd(Source_Control_Internal_2, 0x00C4); + lcd_cmd(Source_OP_Control_Normal , 0x0040); + lcd_cmd(Source_OP_Control_IDLE , 0x0038); + lcd_cmd(0xF1, 0x0001); + lcd_cmd(0xF2, 0x0010); + lcd_cmd(0x27, 0x00A3); + + //power voltage + lcd_cmd(Power_Control_2, 0x001B); + lcd_cmd(Power_Control_1, 0x0001); + lcd_cmd(VCOM_Control_2 , 0x002F); + lcd_cmd(VCOM_Control_3 , 0x0057); + + //VCOM offset + lcd_cmd(VCOM_Control_1, 0x008D); //for flicker adjust + + //power on + lcd_cmd(OSC_Control_1 , 0x0036); + lcd_cmd(OSC_Control_2 , 0x0001); //start osc + lcd_cmd(Display_Mode_Control, 0x0000); //wakeup + lcd_cmd(Power_Control_6 , 0x0088); + systickDelay(5); + lcd_cmd(Power_Control_6, 0x0080); + systickDelay(5); + lcd_cmd(Power_Control_6, 0x0090); + systickDelay(5); + lcd_cmd(Power_Control_6, 0x00D0); + systickDelay(5); + + //color selection + lcd_cmd(COLMOD, 0x0005); //0x0005=65k, 0x0006=262k + + //panel characteristic + lcd_cmd(0x36, 0x0000); + + //display on + lcd_cmd(0x28, 0x0038); + systickDelay(40); + lcd_cmd(0x28, 0x003C); + + lcdSetOrientation(hx8347dPOrientation); + offset = 0; + return; +} +/**************************************************************************/ +/*! + @brief Enables or disables the LCD backlight +*/ +/**************************************************************************/ +void lcdBacklight(bool state) +{ + gpioSetValue(2, LCD_BACK_LIGHT, state); +} + +/**************************************************************************/ +/*! + @brief Renders a simple test pattern on the LCD +*/ +/**************************************************************************/ +void lcdTest(void) +{ + lcdFillRGB(COLOR_CYAN); +} + +/**************************************************************************/ +/*! + @brief Fills the LCD with the specified 16-bit color +*/ +/**************************************************************************/ +void lcdFillRGB(uint16_t data) +{ + lcd_clear(data); +} + +/**************************************************************************/ +/*! + @brief Draws a single pixel at the specified X/Y location +*/ +/**************************************************************************/ +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color) +{ + if((x >= hx8347dProperties.width) || + (y >= hx8347dProperties.height)) + { + return; + } + + fillRect(x,y,x,y,color); + + return; +} + +/**************************************************************************/ +/*! + @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) +{ + lcd_area(x, y, x + len, y); + int i; + lcd_drawstart(); + for(i = 0; i < len; i++) + { + lcd_draw(*data); + data++; + } + lcd_drawstop(); +} + +/**************************************************************************/ +/*! + @brief Optimised routine to draw a horizontal line faster than + setting individual pixels +*/ +/**************************************************************************/ +void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color) +{ + if (x1 < x0) + { + // Switch x1 and x0 + uint16_t x; + x = x1; + x1 = x0; + x0 = x; + } + + if(x0 >= hx8347dProperties.width) + { + x0 = hx8347dProperties.width-1; + } + if(x1 >= hx8347dProperties.width) + { + x1 = hx8347dProperties.width-1; + } + if(y >= hx8347dProperties.height) + { + y = hx8347dProperties.height-1; + } + + fillRect(x0, y, x1, y, 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) +{ + if (y1 < y0) + { + // Switch y1 and y0 + uint16_t y; + y = y1; + y1 = y0; + y0 = y; + } + + if(x >= hx8347dProperties.width) + { + x = hx8347dProperties.width-1; + } + + if(y0 >= hx8347dProperties.height) + { + y0 = hx8347dProperties.height-1; + } + if(y1 >= hx8347dProperties.height) + { + y1 = hx8347dProperties.height-1; + } + + fillRect(x, y0, x, y1, color); +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit color of the pixel at the specified location +*/ +/**************************************************************************/ +uint16_t lcdGetPixel(uint16_t x, uint16_t y) +{ + return 0; +} + +/**************************************************************************/ +/*! + @brief Sets the LCD orientation to horizontal and vertical +*/ +/**************************************************************************/ +void lcdSetOrientation(lcdOrientation_t orientation) +{ + if(orientation == LCD_ORIENTATION_LANDSCAPE) + { + lcd_cmd(0x16, 0x00A8); //MY=1 MX=0 MV=1 ML=0 BGR=1 + hx8347dProperties.width = 320; + hx8347dProperties.height = 240; + } + else + { + //lcd_cmd(0x16, 0x0008); //MY=0 MX=0 MV=0 ML=0 BGR=1 + lcd_cmd(0x16, 0x00C8); //MY=1 MX=0 MV=1 ML=0 BGR=1 + hx8347dProperties.width = 240; + hx8347dProperties.height = 320; + } + hx8347dPOrientation = orientation; + lcd_area(0, 0, (hx8347dProperties.width-1), (hx8347dProperties.height-1)); +} + +/**************************************************************************/ +/*! + @brief Gets the current screen orientation (horizontal or vertical) +*/ +/**************************************************************************/ +lcdOrientation_t lcdGetOrientation(void) +{ + return hx8347dPOrientation; +} + +/**************************************************************************/ +/*! + @brief Gets the width in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetWidth(void) +{ + return hx8347dProperties.width; +} + +/**************************************************************************/ +/*! + @brief Gets the height in pixels of the LCD screen (varies depending + on the current screen orientation) +*/ +/**************************************************************************/ +uint16_t lcdGetHeight(void) +{ + return hx8347dProperties.height; +} + +/**************************************************************************/ +/*! + @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) +{ + hx8347d_Scroll(0,320,0,(offset + pixels) % 320); + if(hx8347dPOrientation == LCD_ORIENTATION_PORTRAIT) + { + fillRect(0, hx8347dProperties.height-pixels, hx8347dProperties.width, hx8347dProperties.height, fillColor); + } + else + { + fillRect(hx8347dProperties.width-pixels, 0, hx8347dProperties.width, hx8347dProperties.height, fillColor); + } + offset = (offset + pixels) % 320; +} +/**************************************************************************/ +/*! + @brief Set LCD into standby + In deep standby: LCD has lower power consumption +*/ +/**************************************************************************/ +void hx8347d_Standby(bool deep) +{ + displayOffFlow(); + lcd_cmd(Power_Control_6 , Power_Control_6_STB); + if(deep) + { + lcd_cmd(Display_Mode_Control,Display_Mode_Control_DP_STB_S); + lcd_cmd(Display_Mode_Control, Display_Mode_Control_DP_STB); + } + lcd_cmd(OSC_Control_2, ~OSC_Control_2_OSC_EN); +} +/**************************************************************************/ +/*! + @brief Wakeup LCD from standby + Wakeup from deep standby you need min. 20ms +*/ +/**************************************************************************/ +void hx8347d_Wakeup(bool deep) +{ + lcd_cmd(OSC_Control_2, OSC_Control_2_OSC_EN); + + if(deep) + { + lcd_cmd(Display_Mode_Control,0x0000); + systickDelay(20); + lcd_cmd(Display_Mode_Control, 0x0000); + } + else + { + systickDelay(5); + } + + lcd_cmd(Power_Control_6, 0x00D0); + displayOnFlow(); +} + +/**************************************************************************/ +/*! + @brief Gets the controller's 16-bit (4 hexdigit) ID +*/ +/**************************************************************************/ +uint16_t lcdGetControllerID(void) +{ + return 0x0; +} + +/**************************************************************************/ +/*! + @brief Returns the LCDs 'lcdProperties_t' that describes the LCDs + generic capabilities and dimensions +*/ +/**************************************************************************/ +lcdProperties_t lcdGetProperties(void) +{ + return hx8347dProperties; +} + diff --git a/drivers/displays/tft/hw/hx8347d.h b/drivers/displays/tft/hw/hx8347d.h new file mode 100644 index 0000000..e86a984 --- /dev/null +++ b/drivers/displays/tft/hw/hx8347d.h @@ -0,0 +1,86 @@ +/**************************************************************************/ +/*! + @file hx8347d.h + @author Tauon {TauonTeilchen} Jabber ID Tauon[at]jabber.ccc.de + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012, TauonTeilchen + ---------------------------------------------------------------------------- + "THE BEER-WARE LICENSE" (Revision 42): + JID: wrote this file. As long as you retain this notice you + can do whatever you want with this stuff. If we meet some day, and you think + this stuff is worth it, you can buy me a ClubMate in return Tauon + ---------------------------------------------------------------------------- + ---------------------------------------------------------------------------- + "THE ClubMate-WARE LICENSE" (Revision 42): + JID: schrieb diese Datei. Solange Sie diesen Vermerk nicht entfernen, koennen + Sie mit dem Material machen, was Sie möechten. Wenn wir uns eines Tages treffen und Sie + denken, das Material ist es wert, koennen Sie mir dafuer ein ClubMate ausgeben. Tauon + ---------------------------------------------------------------------------- +*/ +/**************************************************************************/ + +/**************************************************************************/ +// LCD BACK_LIGHT Pin 6 of Port 2 +// LCD CS Pin 5 of Port 2 +// LCD RESET Pin 4 of Port 2 +// More infos https://github.com/watterott/MI0283QT-Adapter/raw/master/img/connecting-uno.jpg +// +/**************************************************************************/ +#include "core/systick/systick.h" +#include "drivers/displays/tft/touchscreen.h" +#include "core/ssp/ssp.h" +#include "projectconfig.h" +#include "drivers/displays/tft/lcd.h" + + + +// Screen width, height, has touchscreen, support orientation changes, support hw scrolling +static lcdOrientation_t hx8347dPOrientation = LCD_ORIENTATION_LANDSCAPE; + +// Screen width, height, has touchscreen, support orientation changes, support hw scrolling +static lcdProperties_t hx8347dProperties = { 320, 240, false, true, true }; + +/*************************************************/ +/* Private Methods */ +/*************************************************/ + + +/*************************************************/ +/* Public Methods */ +/*************************************************/ + +// The following functions add need to be written to match the generic +// lcd interface defined by lcd.h + +/**************************************************************************/ +/*! + @brief Configures any pins or HW and initialises the LCD controller +*/ +/**************************************************************************/ + +void lcdInit(void); +void lcdBacklight(bool state); +void lcdTest(void); +void lcdFillRGB(uint16_t data); +void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color); +void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len); +void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color); +void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color); +uint16_t lcdGetPixel(uint16_t x, uint16_t y); +void lcdSetOrientation(lcdOrientation_t orientation); +lcdOrientation_t lcdGetOrientation(void); +uint16_t lcdGetWidth(void); +uint16_t lcdGetHeight(void); +void lcdScroll(int16_t pixels, uint16_t fillColor); +uint16_t lcdGetControllerID(void); +lcdProperties_t lcdGetProperties(void); + +void hx8347d_Scroll(uint16_t tfa,uint16_t vsa,uint16_t bfa, uint16_t vsp); +void hx8347d_Standby(bool deep); +void hx8347d_Wakeup(bool deep); + + diff --git a/drivers/displays/tft/hw/readme.txt b/drivers/displays/tft/hw/readme.txt index 9635fc6..e8c0cd9 100644 --- a/drivers/displays/tft/hw/readme.txt +++ b/drivers/displays/tft/hw/readme.txt @@ -2,6 +2,8 @@ HW-Specific TFT and RGB OLED Drivers ==================================== hx8340b - 176x220 16-bit display (Bit-banged SPI interface) +hx8347g - 240x320 16-bit display (8-bit interface) +hx8347h - 240x320 16-bit display (Hardware SPI via SSP0) 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) diff --git a/drivers/sensors/ina219/ina219.c b/drivers/sensors/ina219/ina219.c new file mode 100644 index 0000000..9bdc5dd --- /dev/null +++ b/drivers/sensors/ina219/ina219.c @@ -0,0 +1,569 @@ +/**************************************************************************/ +/*! + @file ina219.c + @author K. Townsend (microBuilder.eu) + + @brief Driver for the TI INA219 current/power monitor + + @section DESCRIPTION + + The INA219 is an I2C-based current/power monitor that monitors the + voltage drop across a shunt resistor, as well as the supply voltage. + + @section EXAMPLE + @code + ina219Init(); + + int16_t current = 0; + int16_t power = 0; + int16_t current_mA = 0; + int16_t power_mW = 0; + int16_t busvoltage = 0; + int16_t shuntvoltage = 0; + int16_t loadVoltage = 0; + + while(1) + { + shuntvoltage = ina219GetShuntVoltage(); + busvoltage = ina219GetBusVoltage(); + power = ina219GetPower(); + current = ina219GetCurrent(); + power_mW = ina219GetPower_mW(); + current_mA = ina219GetCurrent_mA(); + loadVoltage = busvoltage + (shuntvoltage / 100); + printf("%-15s %6d = %d.%dmV (%duV) \r\n", "Shunt Voltage:", shuntvoltage, shuntvoltage / 100, shuntvoltage % 100, shuntvoltage * 10); + printf("%-15s %6d = %d.%dV \r\n", "Bus Voltage:", busvoltage, busvoltage / 1000, busvoltage % 1000); + printf("%-15s %6d = %d.%dV \r\n", "Load Voltage:", loadVoltage, loadVoltage / 1000, loadVoltage % 1000); + printf("%-15s %6d = %dmW \r\n", "Power:", power, power_mW); + printf("%-15s %6d = %dmA \r\n", "Current:", current, current_mA); + printf("\r\n"); + systickDelay(5000); + } + @endcode + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012 Kevin Townsend + 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 "ina219.h" +#include "core/systick/systick.h" + +extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; +extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; + +// The following multipliers are used to convert raw current and power +// values to mA and mW, taking into account the current config settings +uint32_t ina219_currentDivider_mA = 0; +uint32_t ina219_powerDivider_mW = 0; + +/**************************************************************************/ +/*! + @brief Sends a single command byte over I2C +*/ +/**************************************************************************/ +static void ina219WriteRegister (uint8_t reg, uint16_t value) +{ + // Clear write buffers + uint32_t i; + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 4; + I2CReadLength = 0; + I2CMasterBuffer[0] = INA219_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Register + I2CMasterBuffer[2] = value >> 8; // Upper 8-bits + I2CMasterBuffer[3] = value & 0xFF; // Lower 8-bits + i2cEngine(); +} + +/**************************************************************************/ +/*! + @brief Reads a 16 bit values over I2C +*/ +/**************************************************************************/ +static void ina219Read16(uint8_t reg, uint16_t *value) +{ + // Clear write buffers + uint32_t i; + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + I2CWriteLength = 2; + I2CReadLength = 2; + I2CMasterBuffer[0] = INA219_ADDRESS; // I2C device address + I2CMasterBuffer[1] = reg; // Command register + // Append address w/read bit + I2CMasterBuffer[2] = INA219_ADDRESS | INA219_READ; + i2cEngine(); + + // Shift values to create properly formed integer + *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]); +} + +/**************************************************************************/ +/*! + @brief Configures to INA219 to be able to measure up to 32V and 2A + of current. Each unit of current corresponds to 100uA, and + each unit of power corresponds to 2mW. Counter overflow + occurs at 3.2A. + + @note These calculations assume a 0.1 ohm resistor is present +*/ +/**************************************************************************/ +void ina219SetCalibration_32V_2A(void) +{ + // By default we use a pretty huge range for the input voltage, + // which probably isn't the most appropriate choice for system + // that don't use a lot of power. But all of the calculations + // are shown below if you want to change the settings. You will + // also need to change any relevant register settings, such as + // setting the VBUS_MAX to 16V instead of 32V, etc. + + // VBUS_MAX = 32V (Assumes 32V, can also be set to 16V) + // VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04) + // RSHUNT = 0.1 (Resistor value in ohms) + + // 1. Determine max possible current + // MaxPossible_I = VSHUNT_MAX / RSHUNT + // MaxPossible_I = 3.2A + + // 2. Determine max expected current + // MaxExpected_I = 2.0A + + // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) + // MinimumLSB = MaxExpected_I/32767 + // MinimumLSB = 0.000061 (61µA per bit) + // MaximumLSB = MaxExpected_I/4096 + // MaximumLSB = 0,000488 (488µA per bit) + + // 4. Choose an LSB between the min and max values + // (Preferrably a roundish number close to MinLSB) + // CurrentLSB = 0.0001 (100µA per bit) + + // 5. Compute the calibration register + // Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) + // Cal = 4096 (0x1000) + + // 6. Calculate the power LSB + // PowerLSB = 20 * CurrentLSB + // PowerLSB = 0.002 (2mW per bit) + + // 7. Compute the maximum current and shunt voltage values before overflow + // + // Max_Current = Current_LSB * 32767 + // Max_Current = 3.2767A before overflow + // + // If Max_Current > Max_Possible_I then + // Max_Current_Before_Overflow = MaxPossible_I + // Else + // Max_Current_Before_Overflow = Max_Current + // End If + // + // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT + // Max_ShuntVoltage = 0.32V + // + // If Max_ShuntVoltage >= VSHUNT_MAX + // Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX + // Else + // Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage + // End If + + // 8. Computer the Maximum Power + // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX + // MaximumPower = 3.2 * 32V + // MaximumPower = 102.4W + + // Set multipliers to convert raw current/power values + ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10) + ina219_powerDivider_mW = 2; // Power LSB = 1mW per bit (2/1) + + // Set Calibration register to 'Cal' calculated above + ina219WriteRegister(INA219_REG_CALIBRATION, 0x1000); + + // Set Config register to take into account the settings above + uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V | + INA219_CONFIG_GAIN_8_320MV | + INA219_CONFIG_BADCRES_12BIT | + INA219_CONFIG_SADCRES_12BIT_1S_532US | + INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; + ina219WriteRegister(INA219_REG_CONFIG, config); +} + +/**************************************************************************/ +/*! + @brief Configures to INA219 to be able to measure up to 32V and 1A + of current. Each unit of current corresponds to 40uA, and each + unit of power corresponds to 800µW. Counter overflow occurs at + 1.3A. + + @note These calculations assume a 0.1 ohm resistor is present +*/ +/**************************************************************************/ +void ina219SetCalibration_32V_1A(void) +{ + // By default we use a pretty huge range for the input voltage, + // which probably isn't the most appropriate choice for system + // that don't use a lot of power. But all of the calculations + // are shown below if you want to change the settings. You will + // also need to change any relevant register settings, such as + // setting the VBUS_MAX to 16V instead of 32V, etc. + + // VBUS_MAX = 32V (Assumes 32V, can also be set to 16V) + // VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04) + // RSHUNT = 0.1 (Resistor value in ohms) + + // 1. Determine max possible current + // MaxPossible_I = VSHUNT_MAX / RSHUNT + // MaxPossible_I = 3.2A + + // 2. Determine max expected current + // MaxExpected_I = 1.0A + + // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) + // MinimumLSB = MaxExpected_I/32767 + // MinimumLSB = 0.0000305 (30.5µA per bit) + // MaximumLSB = MaxExpected_I/4096 + // MaximumLSB = 0.000244 (244µA per bit) + + // 4. Choose an LSB between the min and max values + // (Preferrably a roundish number close to MinLSB) + // CurrentLSB = 0.0000400 (40µA per bit) + + // 5. Compute the calibration register + // Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) + // Cal = 10240 (0x2800) + + // 6. Calculate the power LSB + // PowerLSB = 20 * CurrentLSB + // PowerLSB = 0.0008 (800µW per bit) + + // 7. Compute the maximum current and shunt voltage values before overflow + // + // Max_Current = Current_LSB * 32767 + // Max_Current = 1.31068A before overflow + // + // If Max_Current > Max_Possible_I then + // Max_Current_Before_Overflow = MaxPossible_I + // Else + // Max_Current_Before_Overflow = Max_Current + // End If + // + // ... In this case, we're good though since Max_Current is less than MaxPossible_I + // + // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT + // Max_ShuntVoltage = 0.131068V + // + // If Max_ShuntVoltage >= VSHUNT_MAX + // Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX + // Else + // Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage + // End If + + // 8. Computer the Maximum Power + // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX + // MaximumPower = 1.31068 * 32V + // MaximumPower = 41.94176W + + // Set multipliers to convert raw current/power values + ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25) + ina219_powerDivider_mW = 1; // Power LSB = 800µW per bit + + // Set Calibration register to 'Cal' calculated above + ina219WriteRegister(INA219_REG_CALIBRATION, 0x2800); + + // Set Config register to take into account the settings above + uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V | + INA219_CONFIG_GAIN_8_320MV | + INA219_CONFIG_BADCRES_12BIT | + INA219_CONFIG_SADCRES_12BIT_1S_532US | + INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; + ina219WriteRegister(INA219_REG_CONFIG, config); +} + +/**************************************************************************/ +/*! + @brief Configures to INA219 to be able to measure up to 16V and 500mA + of current. Each unit of current corresponds to 25uA, and each + unit of power corresponds to 500µW. Counter overflow occurs at + 800mA. + + @note These calculations assume a 0.1 ohm resistor is present +*/ +/**************************************************************************/ +void ina219SetCalibration_16V_500mA(void) +{ + // VBUS_MAX = 16V + // VSHUNT_MAX = 0.08 (Assumes Gain 2, 80mV, can also be 0.32, 0.16, 0.04) + // RSHUNT = 0.1 (Resistor value in ohms) + + // 1. Determine max possible current + // MaxPossible_I = VSHUNT_MAX / RSHUNT + // MaxPossible_I = 0.8A + + // 2. Determine max expected current + // MaxExpected_I = 0.5A + + // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) + // MinimumLSB = MaxExpected_I/32767 + // MinimumLSB = 0.0000153 (15.3µA per bit) + // MaximumLSB = MaxExpected_I/4096 + // MaximumLSB = 0.0001221 (122µA per bit) + + // 4. Choose an LSB between the min and max values + // (Preferrably a roundish number close to MinLSB) + // CurrentLSB = 0.0000250 (25µA per bit) + + // 5. Compute the calibration register + // Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) + // Cal = 16384 (0x4000) + + // 6. Calculate the power LSB + // PowerLSB = 20 * CurrentLSB + // PowerLSB = 0.0005 (500µW per bit) + + // 7. Compute the maximum current and shunt voltage values before overflow + // + // Max_Current = Current_LSB * 32767 + // Max_Current = 0.819175 (819 mA before overflow) + // + // If Max_Current > Max_Possible_I then + // Max_Current_Before_Overflow = MaxPossible_I + // Else + // Max_Current_Before_Overflow = Max_Current + // End If + // + // Max_Current_Before_Overflow = 0.8A + // + // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT + // Max_ShuntVoltage = 0.8 * 0.1 + // Max_ShuntVoltage = 0.08V + // + // If Max_ShuntVoltage >= VSHUNT_MAX + // Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX + // Else + // Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage + // End If + + // 8. Computer the Maximum Power + // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX + // MaximumPower = 0.8 * 16V + // MaximumPower = 12.8W + + // Set multipliers to convert raw current/power values + ina219_currentDivider_mA = 40; // Current LSB = 25uA per bit (1000/25 = 40) + ina219_powerDivider_mW = 1; // Power LSB = 500µW per bit + + // Set Calibration register to 'Cal' calculated above + ina219WriteRegister(INA219_REG_CALIBRATION, 0x4000); + + // Set Config register to take into account the settings above + uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V | + INA219_CONFIG_GAIN_2_80MV | + INA219_CONFIG_BADCRES_12BIT | + INA219_CONFIG_SADCRES_12BIT_1S_532US | + INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; + ina219WriteRegister(INA219_REG_CONFIG, config); +} + +/**************************************************************************/ +/*! + @brief Configures to INA219 to be able to measure up to 16V and 200mA + of current. Each unit of current corresponds to 10uA, and each + unit of power corresponds to 200µW. Counter overflow occurs at + 327mA. + + @note These calculations assume a 0.1 ohm resistor is present +*/ +/**************************************************************************/ +void ina219SetCalibration_16V_200mA(void) +{ + // VBUS_MAX = 16V + // VSHUNT_MAX = 0.04 (Assumes Gain 1, 40mV, can also be 0.32, 0.16, 0.08) + // RSHUNT = 0.1 (Resistor value in ohms) + + // 1. Determine max possible current + // MaxPossible_I = VSHUNT_MAX / RSHUNT + // MaxPossible_I = 0.4A + + // 2. Determine max expected current + // MaxExpected_I = 0.2A + + // 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit) + // MinimumLSB = MaxExpected_I/32767 + // MinimumLSB = 0.000006104 (6.104µA per bit) + // MaximumLSB = MaxExpected_I/4096 + // MaximumLSB = 0,000048828 (48.82µA per bit) + + // 4. Choose an LSB between the min and max values + // CurrentLSB = 0.000010 (10µA per bit) + + // 5. Compute the calibration register + // Cal = trunc (0.04096 / (Current_LSB * RSHUNT)) + // Cal = 40960 (0xA000) + + // 6. Calculate the power LSB + // PowerLSB = 20 * CurrentLSB + // PowerLSB = 0.0002 (200µW per bit) + + // 7. Compute the maximum current and shunt voltage values before overflow + // + // Max_Current = Current_LSB * 32767 + // Max_Current = 0.32767 (328 mA before overflow) + // + // If Max_Current > Max_Possible_I then + // Max_Current_Before_Overflow = MaxPossible_I + // Else + // Max_Current_Before_Overflow = Max_Current + // End If + // + // Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT + // Max_ShuntVoltage = 0.032767V + // + // If Max_ShuntVoltage >= VSHUNT_MAX + // Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX + // Else + // Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage + // End If + + // 8. Computer the Maximum Power + // MaximumPower = Max_Current_Before_Overflow * VBUS_MAX + // MaximumPower = 0.32767 * 16V + // MaximumPower = 5.24W + + // Set multipliers to convert raw current/power values + ina219_currentDivider_mA = 100; // Current LSB = 10uA per bit (1000/10 = 100) + ina219_powerDivider_mW = 1; // Power LSB = 200µW per bit + + // Set Calibration register to 'Cal' calculated above + ina219WriteRegister(INA219_REG_CALIBRATION, 0xA000); + + // Set Config register to take into account the settings above + uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V | + INA219_CONFIG_GAIN_1_40MV | + INA219_CONFIG_BADCRES_12BIT | + INA219_CONFIG_SADCRES_12BIT_1S_532US | + INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; + ina219WriteRegister(INA219_REG_CONFIG, config); +} + +/**************************************************************************/ +/*! + @brief Initialises the I2C block +*/ +/**************************************************************************/ +void ina219Init(void) +{ + // Reset INA219 (set to default values) + ina219WriteRegister(INA219_REG_CONFIG, INA219_CONFIG_RESET); + + // Setup chip for 32V and 2A by default + ina219SetCalibration_32V_2A(); +} + +/**************************************************************************/ +/*! + @brief Gets the shunt voltage (16-bit signed integer, so +-32767) +*/ +/**************************************************************************/ +int16_t ina219GetShuntVoltage(void) +{ + uint16_t value; + ina219Read16(INA219_REG_SHUNTVOLTAGE, &value); + return value; +} + +/**************************************************************************/ +/*! + @brief Gets the shunt voltage (16-bit signed integer, so +-32767) +*/ +/**************************************************************************/ +int16_t ina219GetBusVoltage(void) +{ + uint16_t value; + ina219Read16(INA219_REG_BUSVOLTAGE, &value); + // Shift to the right 3 to drop CNVR and OVF and then multiply by LSB + return (value >> 3) * 4; +} + +/**************************************************************************/ +/*! + @brief Gets the raw power value (16-bit signed integer, so +-32767) +*/ +/**************************************************************************/ +int16_t ina219GetPower(void) +{ + uint16_t value; + ina219Read16(INA219_REG_POWER, &value); + return value; +} + +/**************************************************************************/ +/*! + @brief Gets the power value in mW, taking into account the config + settings and power LSB +*/ +/**************************************************************************/ +int16_t ina219GetPower_mW(void) +{ + uint16_t value; + ina219Read16(INA219_REG_POWER, &value); + return value / ina219_powerDivider_mW; +} + +/**************************************************************************/ +/*! + @brief Gets the raw current value (16-bit signed integer, so +-32767) +*/ +/**************************************************************************/ +int16_t ina219GetCurrent(void) +{ + uint16_t value; + ina219Read16(INA219_REG_CURRENT, &value); + return value; +} + +/**************************************************************************/ +/*! + @brief Gets the current value in mA, taking into account the + config settings and current LSB +*/ +/**************************************************************************/ +int16_t ina219GetCurrent_mA(void) +{ + uint16_t value; + ina219Read16(INA219_REG_CURRENT, &value); + return value / ina219_currentDivider_mA; +} + + diff --git a/drivers/sensors/ina219/ina219.h b/drivers/sensors/ina219/ina219.h new file mode 100644 index 0000000..69dfdbc --- /dev/null +++ b/drivers/sensors/ina219/ina219.h @@ -0,0 +1,137 @@ +/**************************************************************************/ +/*! + @file ina219.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2012 Kevin Townsend + 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 _INA219_H_ +#define _INS219_H_ + +#include "projectconfig.h" +#include "core/i2c/i2c.h" + +/*========================================================================= + I2C ADDRESS/BITS + -----------------------------------------------------------------------*/ + #define INA219_ADDRESS (0x80) // 1000000x (A0+A1=GND) + #define INA219_READ (0x01) +/*=========================================================================*/ + +/*========================================================================= + CONFIG REGISTER (R/W) + -----------------------------------------------------------------------*/ + #define INA219_REG_CONFIG (0x00) + /*---------------------------------------------------------------------*/ + #define INA219_CONFIG_RESET (0x8000) // Reset Bit + + #define INA219_CONFIG_BVOLTAGERANGE_MASK (0x4000) // Bus Voltage Range Mask + #define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range + #define INA219_CONFIG_BVOLTAGERANGE_32V (0x4000) // 0-32V Range + + #define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask + #define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range + #define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range + #define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range + #define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range + + #define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask + #define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511 + #define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023 + #define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047 + #define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097 + + #define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask + #define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample + #define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample + #define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample + #define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample + #define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together + #define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together + + #define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask + #define INA219_CONFIG_MODE_POWERDOWN (0x0000) + #define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001) + #define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002) + #define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003) + #define INA219_CONFIG_MODE_ADCOFF (0x0004) + #define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005) + #define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006) + #define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007) +/*=========================================================================*/ + +/*========================================================================= + SHUNT VOLTAGE REGISTER (R) + -----------------------------------------------------------------------*/ + #define INA219_REG_SHUNTVOLTAGE (0x01) +/*=========================================================================*/ + +/*========================================================================= + BUS VOLTAGE REGISTER (R) + -----------------------------------------------------------------------*/ + #define INA219_REG_BUSVOLTAGE (0x02) +/*=========================================================================*/ + +/*========================================================================= + POWER REGISTER (R) + -----------------------------------------------------------------------*/ + #define INA219_REG_POWER (0x03) +/*=========================================================================*/ + +/*========================================================================= + CURRENT REGISTER (R) + -----------------------------------------------------------------------*/ + #define INA219_REG_CURRENT (0x04) +/*=========================================================================*/ + +/*========================================================================= + CALIBRATION REGISTER (R/W) + -----------------------------------------------------------------------*/ + #define INA219_REG_CALIBRATION (0x05) +/*=========================================================================*/ + +void ina219Init(void); +int16_t ina219GetShuntVoltage(void); +int16_t ina219GetBusVoltage(void); +int16_t ina219GetPower(void); +int16_t ina219GetPower_mW(void); +int16_t ina219GetCurrent(void); +int16_t ina219GetCurrent_mA(void); + +#endif + + diff --git a/main.c b/main.c index bb2c280..80c0e8e 100644 --- a/main.c +++ b/main.c @@ -7,7 +7,7 @@ Software License Agreement (BSD License) - Copyright (c) 2012, microBuilder SARL + Copyright (c) 2011, microBuilder SARL All rights reserved. Redistribution and use in source and binary forms, with or without @@ -33,6 +33,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /**************************************************************************/ +#include +#include +#include + #include "projectconfig.h" #include "sysinit.h" @@ -56,7 +60,7 @@ int main(void) uint32_t currentSecond, lastSecond; currentSecond = lastSecond = 0; - + while (1) { // Toggle LED once per second diff --git a/project/cmd_tbl.h b/project/cmd_tbl.h index 639503c..83d3880 100644 --- a/project/cmd_tbl.h +++ b/project/cmd_tbl.h @@ -159,7 +159,7 @@ cmd_t cmd_tbl[] = #endif #ifdef CFG_PWM - { "M", 0, 2, 0, cmd_pwm , "PWM Control" , "'M [] []'" }, + { "M", 2, 2, 0, cmd_pwm , "PWM Control" , "'M [] []'" }, #endif }; diff --git a/project/commands/cmd_pwm.c b/project/commands/cmd_pwm.c index 505470d..3d070d5 100644 --- a/project/commands/cmd_pwm.c +++ b/project/commands/cmd_pwm.c @@ -56,38 +56,29 @@ void cmd_pwm(uint8_t argc, char **argv) { int32_t frequencyTicks = 65535; int32_t dutyCycle = CFG_PWM_DEFAULT_DUTYCYCLE; - if(argc > 0) { - getNumber (argv[0], &dutyCycle); - if(dutyCycle < 1 || dutyCycle > 100) { - printf("Invalid duty cycle [1..65535]%s", CFG_PRINTF_NEWLINE); - return; - } - - if(argc > 1) { - getNumber (argv[1], &frequencyTicks); - if(frequencyTicks < 0 || frequencyTicks > 0xffff) { - printf("Invalid frequency [1..65535]%s", CFG_PRINTF_NEWLINE); - return; - } - } else { - frequencyTicks = 65535; - } - } else { - dutyCycle = CFG_PWM_DEFAULT_DUTYCYCLE; + getNumber (argv[0], &dutyCycle); + if(dutyCycle < 1 || dutyCycle > 100) + { + printf("Invalid duty cycle [1..65535]%s", CFG_PRINTF_NEWLINE); + return; } - if(! pwmStarted) { - printf("Initializing PWM%s", CFG_PRINTF_NEWLINE); - pwmInit(); + getNumber (argv[1], &frequencyTicks); + if(frequencyTicks < 0 || frequencyTicks > 0xffff) + { + printf("Invalid frequency [1..65535]%s", CFG_PRINTF_NEWLINE); + return; } - + printf("Setting frequency: %u ticks%s", (uint16_t) frequencyTicks, CFG_PRINTF_NEWLINE); pwmSetFrequencyInTicks(frequencyTicks); printf("Setting duty cycle: %u%%%s", (uint16_t) dutyCycle, CFG_PRINTF_NEWLINE); pwmSetDutyCycle(dutyCycle); - if(! pwmStarted) { - pwmStart(); - pwmStarted = 1; + if(! pwmStarted) + { + printf("Initializing PWM%s", CFG_PRINTF_NEWLINE); + pwmStart(); + pwmStarted = 1; } } #endif diff --git a/projectconfig.h b/projectconfig.h index 1d3c92f..f9f1e3f 100644 --- a/projectconfig.h +++ b/projectconfig.h @@ -196,12 +196,12 @@ LM75B 0x90 1001000x MCP24AA 0xA0 1010000x MCP4725 0xC0 1100000x *** - TEA5767 0xC0 1100000x *** + TEA5767 0xC0 1100000x *** TSL2561 0x72 0111001x TCS3414 0x72 0111001x PN532 0x48 0100100x SSD1306_I2C 0x78 0111100x // Assumes SA0 = GND - INA219 0xF0 10000000x // Assumes A0+A1 = GND + INA219 0xF0 10000000x // Assumes A0+A1 = GND [1] Alternative addresses may exists, but the addresses listed in this table are the values used in the code base diff --git a/tools/testfirmware/LPC1343_LCDStandalone_UART_LF.bin b/tools/testfirmware/LPC1343_LCDStandalone_UART_LF.bin deleted file mode 100644 index c9fda07..0000000 Binary files a/tools/testfirmware/LPC1343_LCDStandalone_UART_LF.bin and /dev/null differ diff --git a/tools/testfirmware/LPC1343_LCDStandalone_USB_CRLF.bin b/tools/testfirmware/LPC1343_LCDStandalone_USB_CRLF.bin deleted file mode 100644 index bc623c4..0000000 Binary files a/tools/testfirmware/LPC1343_LCDStandalone_USB_CRLF.bin and /dev/null differ diff --git a/tools/testfirmware/blinky.bin b/tools/testfirmware/blinky.bin deleted file mode 100644 index bacaf86..0000000 Binary files a/tools/testfirmware/blinky.bin and /dev/null differ diff --git a/tools/testfirmware/blinky_usbcli.bin b/tools/testfirmware/blinky_usbcli.bin new file mode 100644 index 0000000..5cd75fe Binary files /dev/null and b/tools/testfirmware/blinky_usbcli.bin differ diff --git a/tools/testfirmware/uartcli.bin b/tools/testfirmware/uartcli.bin deleted file mode 100644 index 263ef63..0000000 Binary files a/tools/testfirmware/uartcli.bin and /dev/null differ diff --git a/tools/validation/startupdelay/StartupTime_CrossworksForARM.png b/tools/validation/startupdelay/StartupTime_CrossworksForARM.png new file mode 100644 index 0000000..9393c6e Binary files /dev/null and b/tools/validation/startupdelay/StartupTime_CrossworksForARM.png differ diff --git a/tools/validation/startupdelay/StartupTime_GCCMakefile.png b/tools/validation/startupdelay/StartupTime_GCCMakefile.png new file mode 100644 index 0000000..00c4297 Binary files /dev/null and b/tools/validation/startupdelay/StartupTime_GCCMakefile.png differ diff --git a/tools/validation/startupdelay/main.c b/tools/validation/startupdelay/main.c new file mode 100644 index 0000000..8b49653 --- /dev/null +++ b/tools/validation/startupdelay/main.c @@ -0,0 +1,71 @@ +/**************************************************************************/ +/*! + @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 "projectconfig.h" + +#include "core/gpio/gpio.h" + +/**************************************************************************/ +/*! + As soon as the chip comes out of reset and the startup code has + finished executing, sets up GPIO pin 2.1 as an ouput and high. + + This can be used to determine the startup delay, by measuring the + time between reset be deasserted and the GPIO pin going high, minus + the GPIO overhead of a few clock cycles. + + HW Setup: Set channel one of the oscilliscope to the reset pin, and + channel two of the oscilliscope to GPIO pin 2.1. + + Set a trigger on the rising edge of the reset pin, and + measure the delay between the rising edge of reset and the + rising edge of GPIO 2.1. +*/ +/**************************************************************************/ +int main(void) +{ + /* Enable AHB clock to the GPIO domain. */ + SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_GPIO); + + /* Set 2.1 to output and high */ + GPIO_GPIO2DIR |= (1 << 1); // pin 1 = Output + GPIO_GPIO2DATA |= (1 << 1); // pin 1 = High + + while(1) + { + } + + return 0; +} diff --git a/tools/validation/startupdelay/readme.txt b/tools/validation/startupdelay/readme.txt new file mode 100644 index 0000000..923cd79 --- /dev/null +++ b/tools/validation/startupdelay/readme.txt @@ -0,0 +1,16 @@ +This simple code can be used to test the startup delay, or more precisely +the delay between the moment that reset is deasserted and code execution +begins in main(). + +GPIO pin 2.1 is set to output and high as soon as main is entered, so you +simply need to monitor the reset line and GPIO 2.1 on a two-channel +oscilliloscope, and measure the delay between the two rising edges. + +Two sample tests results are showing for GCC with a Makefile and with +Crossworks for ARM. Both examples are included since the startup code +for both project types is slightly different, with Crossworks using a +custom startup file provided by Rowley Associates, and the LPC1343 +Code Base using it's own startup code when compiling with make and GCC. + +Note: This code is only useful for measuring the time coming out of +reset, not from a cold boot (applying power to an unpowered device). \ No newline at end of file