v0.9.8 - Ongoing
================
+- Added driver for Samsung VFD displays from Adafruit
+- Added average sampling option to projectconfig.h.
+ This allows you to take several readings from the
+ ADC and return the average. Helps reduces one-off
+ peaks and valleys in the ADC at the expense of
+ slower reads.
+ See: "tools/validation/adctest" for more info
- Added I2C driver for PN532
- Updated and added PN532 examples at
/tools/examples/sensors/PN532
<configuration Name="THUMB Flash Release" build_exclude_from_build="No"/>
</file>
<file file_name="../../drivers/lcd/icons16.h"/>
+ <folder Name="character">
+ <folder Name="samsung_20T202DA2JA">
+ <file file_name="../../drivers/lcd/character/samsung_20T202DA2JA/samsung_20T202DA2JA.c"/>
+ </folder>
+ </folder>
</folder>
<folder Name="fatfs" file_name="">
<file file_name="../../drivers/fatfs/ff.c">
<ProjectSessionItem path="LPC1343_CodeBase" name="unnamed" />
<ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase" name="unnamed" />
<ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;core" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;core;gpio" name="unnamed" />
<ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers" name="unnamed" />
- <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;sensors" name="unnamed" />
- <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;sensors;pn532" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;lcd" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;lcd;bitmap" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;lcd;bitmap;ssd1306" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;lcd;character" name="unnamed" />
+ <ProjectSessionItem path="LPC1343_CodeBase;LPC1343_CodeBase;Source Files;drivers;lcd;character;samsung_20T202DA2JA" name="unnamed" />
</Project>
<Register1>
<RegisterWindow openNodes="USB;USB/USBRxPLen;USB/USBTxPLen;USB/USBCtrl" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="CPU;USB" decimalNodes="" octalNodes="" asciiNodes="" />
<Watches active="0" update="Never" />
</Watch4>
<Files>
- <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="72" debugPath="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\main.c" y="16" path="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\main.c" left="0" selected="1" name="unnamed" top="0" />
+ <SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="28" debugPath="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\main.c" y="45" path="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\main.c" left="0" selected="1" name="unnamed" top="39" />
</Files>
- <ARMCrossStudioWindow activeProject="LPC1343_CodeBase" autoConnectTarget="Segger J-Link" debugSearchFileMap="" fileDialogInitialDirectory="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\drivers\sensors\pn532" fileDialogDefaultFilter="" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Release" />
+ <ARMCrossStudioWindow activeProject="LPC1343_CodeBase" autoConnectTarget="SEGGER J-Link" debugSearchFileMap="" fileDialogInitialDirectory="C:\Dropbox\microBuilder\Code\LPC1343\LPC1343_CodeBase_GIT\drivers\lcd\character\samsung_20T202DA2JA" fileDialogDefaultFilter="" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Release" />
</session>
be added to the adcInit function.
*/
/**************************************************************************/
-uint32_t adcRead (uint8_t channelNum)
+uint32_t adcReadSingle (uint8_t channelNum)
{
if (!_adcInitialised) adcInit();
return (adcData);
}
+/**************************************************************************/
+/*!
+ @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. If ADC Averaging is enabled
+ (via ADC_AVERAGING_ENABLE) the specified number of values will be
+ samples from the ADC and the average value will be returned.
+
+ @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();
+
+ #if ADC_AVERAGING_ENABLE
+ uint32_t adcTotal, i;
+ adcTotal = 0;
+ for (i=0; i<ADC_AVERAGING_SAMPLES;i++)
+ {
+ adcTotal += adcReadSingle(channelNum);
+ }
+ return adcTotal/ADC_AVERAGING_SAMPLES;
+ #else
+ return adcReadSingle(channelNum);
+ #endif
+}
+
/**************************************************************************/
/*!
@brief Initialises the A/D converter and configures channels 0..3
* Major cleaning and a rewrite of some functions
* - adding ACK/NACK handling to the state machine
* - adding a return result to the I2CEngine()
+ * 2011.02.19 ver 1.20 KTownsend - microBuilder.eu
+ * - Added slave mode status values to
+ * I2C_IRQHandler
*
*****************************************************************************/
#include "i2c.h"
volatile uint32_t I2CMasterState = I2CSTATE_IDLE;
volatile uint32_t I2CSlaveState = I2CSTATE_IDLE;
-volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
-volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
+volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; // Master Mode
+volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; // Master Mode
+
+//volatile uint8_t I2CWrBuffer[I2C_BUFSIZE]; // Slave Mode
+//volatile uint8_t I2CRdBuffer[I2C_BUFSIZE]; // Slave Mode
+
volatile uint32_t I2CReadLength;
volatile uint32_t I2CWriteLength;
-volatile uint32_t RdIndex = 0;
-volatile uint32_t WrIndex = 0;
+volatile uint32_t RdIndex;
+volatile uint32_t WrIndex;
+volatile uint32_t _I2cMode; // I2CMASTER or I2CSLAVE
/*****************************************************************************
** Function name: I2C_IRQHandler
I2C_I2CCONCLR = I2CONCLR_SIC; /* Clear SI flag */
break;
-
+
+ /* Slave Mode */
+
+// case 0x60: /* An own SLA_W has been received. */
+// case 0x70:
+// RdIndex = 0;
+// I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after SLV_W is received */
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// I2CSlaveState = I2C_WR_STARTED;
+// break;
+//
+// case 0x80: /* data receive */
+// case 0x90:
+// if ( I2CSlaveState == I2C_WR_STARTED )
+// {
+// I2CRdBuffer[RdIndex++] = I2C_I2CDAT;
+// I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after data is received */
+// }
+// else
+// {
+// I2C_I2CCONCLR = I2CONCLR_AAC; /* assert NACK */
+// }
+// // ToDo: Set a flag to indicate data is ready and process it somewhere
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// break;
+//
+// case 0xA8: /* An own SLA_R has been received. */
+// case 0xB0:
+// // RdIndex = 0;
+// WrIndex = I2CRdBuffer[0]; /* The 1st byte is the index. */
+// I2C_I2CDAT = I2CRdBuffer[WrIndex+1]; /* write the same data back to master */
+// WrIndex++; /* Need to skip the index byte in RdBuffer */
+// I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after SLV_R is received */
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// I2CSlaveState = I2C_RD_STARTED;
+// break;
+//
+// case 0xB8: /* Data byte has been transmitted */
+// case 0xC8:
+// if ( I2CSlaveState == I2C_RD_STARTED )
+// {
+// I2C_I2CDAT = I2CRdBuffer[WrIndex+1]; /* write the same data back to master */
+// WrIndex++; /* Need to skip the index byte in RdBuffer */
+// I2C_I2CCONSET = I2CONSET_AA; /* assert ACK */
+// }
+// else
+// {
+// I2C_I2CCONCLR = I2CONCLR_AAC; /* assert NACK */
+// }
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// break;
+//
+// case 0xC0: /* Data byte has been transmitted, NACK */
+// I2C_I2CCONCLR = I2CONCLR_AAC; /* assert NACK */
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// I2CSlaveState = DATA_NACK;
+// break;
+//
+// case 0xA0: /* Stop condition or repeated start has */
+// I2C_I2CCONSET = I2CONSET_AA; /* been received, assert ACK. */
+// I2C_I2CCONCLR = I2CONCLR_SIC;
+// I2CSlaveState = I2C_IDLE;
+// break;
+
default:
- I2C_I2CCONCLR = I2CONCLR_SIC;
- break;
+ I2C_I2CCONCLR = I2CONCLR_SIC;
+// if (_I2cMode = I2CSLAVE)
+// {
+// I2C_I2CCONSET = I2CONSET_I2EN | I2CONSET_SI;
+// }
+ break;
}
return;
}
*****************************************************************************/
static uint32_t I2CStart( void )
{
- uint32_t timeout = 0;
-
- /*--- Issue a start condition ---*/
- I2C_I2CCONSET = I2CONSET_STA; /* Set Start flag */
-
- while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT))
- {
- timeout++;
- }
-
- return (timeout < MAX_TIMEOUT);
+ uint32_t timeout = 0;
+
+ /*--- Issue a start condition ---*/
+ I2C_I2CCONSET = I2CONSET_STA; /* Set Start flag */
+
+ while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT))
+ {
+ timeout++;
+ }
+
+ return (timeout < MAX_TIMEOUT);
}
/*****************************************************************************
*****************************************************************************/
static uint32_t I2CStop( void )
{
- uint32_t timeout = 0;
-
- I2C_I2CCONSET = I2CONSET_STO; /* Set Stop flag */
- I2C_I2CCONCLR = I2CONCLR_SIC; /* Clear SI flag */
-
- /*--- Wait for STOP detected ---*/
- while((I2C_I2CCONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT))
- {
- timeout++;
- }
- return (timeout >= MAX_TIMEOUT);
+ uint32_t timeout = 0;
+
+ I2C_I2CCONSET = I2CONSET_STO; /* Set Stop flag */
+ I2C_I2CCONCLR = I2CONCLR_SIC; /* Clear SI flag */
+
+ /*--- Wait for STOP detected ---*/
+ while((I2C_I2CCONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT))
+ {
+ timeout++;
+ }
+ return (timeout >= MAX_TIMEOUT);
}
/*****************************************************************************
*****************************************************************************/
uint32_t i2cInit( uint32_t I2cMode )
{
+ _I2cMode = I2cMode;
+
SCB_PRESETCTRL |= (0x1<<1);
// Enable I2C clock
I2C_I2CSCLH = I2SCLH_SCLH;
#endif
- if ( I2cMode == I2CSLAVE )
+ if ( _I2cMode == I2CSLAVE )
{
I2C_I2CADR0 = SLAVE_ADDR;
- }
+ I2CSlaveState = I2C_IDLE;
+ }
/* Enable the I2C Interrupt */
NVIC_EnableIRQ(I2C_IRQn);
- I2C_I2CCONSET = I2C_I2CCONSET_I2EN;
+ if ( _I2cMode == I2CMASTER )
+ {
+ I2C_I2CCONSET = I2C_I2CCONSET_I2EN;
+ }
+// else
+// {
+// I2C_I2CCONSET = I2C_I2CCONSET_I2EN | I2C_I2CCONSET_SI;
+// }
return( TRUE );
}
return ( I2CMasterState );
}
-/*****************************************************************************
-** Function name: i2cSendGeneralCall
-**
-** Descriptions: Sends a request to the general call address (0x00)
-** which should detect if there are any devices on the
-** i2c bus. For more information see:
-** http://www.i2c-bus.org/addressing/general-call-address/
-**
-** parameters: None
-** Returned value: Any of the I2CSTATE_... values. See i2c.h
-**
-*****************************************************************************/
-uint32_t i2cSendGeneralCall(void)
-{
- uint32_t i2cState;
-
- // Clear write buffers
- uint32_t i;
- for ( i = 0; i < I2C_BUFSIZE; i++ )
- {
- I2CMasterBuffer[i] = 0x00;
- }
-
- // Send the specified bytes
- I2CWriteLength = 1;
- I2CReadLength = 0;
- I2CMasterBuffer[0] = I2C_GENERALCALL;
- i2cState = i2cEngine();
-
- return i2cState;
-}
-
/******************************************************************************
** End Of File
******************************************************************************/
* 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
+ * 2011.02.19 ver 1.20 KTownsend - microBuilder.eu
+ * - Added slave mode status values to
+ * I2C_IRQHandler
*
******************************************************************************/
#ifndef __I2C_H
* 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 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 FAST_MODE_PLUS 0
-#define I2C_BUFSIZE 64
-#define MAX_TIMEOUT 0x00FFFFFF
+#define I2C_BUFSIZE 64
+#define MAX_TIMEOUT 0x00FFFFFF
-#define I2CMASTER 0x01
-#define I2CSLAVE 0x02
+#define I2CMASTER 0x01
+#define I2CSLAVE 0x02
-#define SLAVE_ADDR 0xA0
-#define READ_WRITE 0x01
+#define SLAVE_ADDR 0xA0
+#define READ_WRITE 0x01
-#define RD_BIT 0x01
+#define RD_BIT 0x01
-#define I2C_GENERALCALL 0x00 /* General Call Address (to 'ping' I2C bus for devices) */
+#define I2C_GENERALCALL 0x00 /* General Call Address (to 'ping' I2C bus for devices) */
-#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 I2C_IDLE 0
+#define I2C_STARTED 1
+#define I2C_RESTARTED 2
+#define I2C_REPEATED_START 3
+#define DATA_ACK 4
+#define DATA_NACK 5
+#define I2C_WR_STARTED 6
+#define I2C_RD_STARTED 7
-#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
-#define I2CONCLR_SIC 0x00000008
-#define I2CONCLR_STAC 0x00000020
-#define I2CONCLR_I2ENC 0x00000040
+/* I2C Control Set Register */
+#define I2CONSET_I2EN 0x00000040 /* I2C Interface Enable */
+#define I2CONSET_AA 0x00000004 /* Assert acknowledge flag */
+#define I2CONSET_SI 0x00000008 /* I2C interrupt flag */
+#define I2CONSET_STO 0x00000010 /* STOP flag */
+#define I2CONSET_STA 0x00000020 /* START flag */
-#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
-#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
+/* I2C Control clear Register */
+#define I2CONCLR_AAC 0x00000004 /* Assert acklnowedge clear bit*/
+#define I2CONCLR_SIC 0x00000008 /* I2C interrupt clear bit */
+#define I2CONCLR_STAC 0x00000020 /* START flag clear bit */
+#define I2CONCLR_I2ENC 0x00000040 /* I2C interface disable bit */
+
+#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
+#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
/* SCLH and SCLL = I2C PCLK High/Low cycles for I2C clock and
determine the data rate/duty cycle for I2C:
#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 */
-extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
-extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; // Master Mode
+extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; // Master Mode
+// extern volatile uint8_t I2CWrBuffer[I2C_BUFSIZE]; // Slave Mode
+// extern volatile uint8_t I2CRdBuffer[I2C_BUFSIZE]; // Slave Mode
extern volatile uint32_t I2CReadLength, I2CWriteLength;
extern void I2C_IRQHandler( void );
extern uint32_t i2cInit( uint32_t I2cMode );
extern uint32_t i2cEngine( void );
-uint32_t i2cSendGeneralCall( void );
#endif /* end __I2C_H */
/****************************************************************************
--- /dev/null
+/**************************************************************************/
+/*!
+ @file samsung_20T202DA2JA.c
+ @author Original source : Limor Fried/ladyada (Adafruit Industries)
+ LPC1343 port : K. Townsend
+
+ @section DESCRIPTION
+
+ Driver for Samsung 20T202DA2JA 20x2 VFD display module.
+
+ This driver is based on the SPI_VFD Library from Limor Fried
+ (Adafruit Industries) at: https://github.com/adafruit/SPI_VFD
+
+ The displays can be purchased at:
+ https://www.adafruit.com/products/347
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2012 Adafruit Industries
+ 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 <string.h>
+
+#include "samsung_20T202DA2JA.h"
+
+#include "core/gpio/gpio.h"
+#include "core/systick/systick.h"
+
+/**************************************************************************/
+/* Private Methods */
+/**************************************************************************/
+
+uint8_t samsungvfd_displayfunction;
+uint8_t samsungvfd_displaycontrol;
+uint8_t samsungvfd_displaymode;
+uint8_t samsungvfd_initialized;
+uint8_t samsungvfd_numlines, samsungvfd_currline;
+
+/**************************************************************************/
+/*!
+ @brief Low-level SPI bit-banging routing
+*/
+/**************************************************************************/
+static inline void samsungvfd_sendByte(uint8_t c) {
+ int8_t i;
+
+ // Make sure clock pin starts high
+ gpioSetValue(SAMSUNGVFD_SCK_PORT, SAMSUNGVFD_SCK_PIN, 1);
+
+ // Write from MSB to LSB
+ for (i=7; i>=0; i--)
+ {
+ // Set clock pin low
+ gpioSetValue(SAMSUNGVFD_SCK_PORT, SAMSUNGVFD_SCK_PIN, 0);
+ // Set data pin high or low depending on the value of the current bit
+ gpioSetValue(SAMSUNGVFD_SIO_PORT, SAMSUNGVFD_SIO_PIN, c & (1 << i) ? 1 : 0);
+ // Set clock pin high
+ gpioSetValue(SAMSUNGVFD_SCK_PORT, SAMSUNGVFD_SCK_PIN, 1);
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Sends a command to the VFD display
+*/
+/**************************************************************************/
+void samsungvfd_command(uint8_t value)
+{
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 0);
+ samsungvfd_sendByte(SAMSUNGVFD_SPICOMMAND);
+ samsungvfd_sendByte(value);
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 1);
+}
+
+/**************************************************************************/
+/*!
+ @brief Initialises the VFD character display
+*/
+/**************************************************************************/
+void samsungvfd_begin(uint8_t cols, uint8_t lines, uint8_t brightness)
+{
+ // set number of lines
+ if (lines > 1)
+ samsungvfd_displayfunction = SAMSUNGVFD_2LINE;
+ else
+ samsungvfd_displayfunction = SAMSUNGVFD_1LINE;
+
+ if (brightness>SAMSUNGVFD_BRIGHTNESS25) //catch bad values
+ brightness = SAMSUNGVFD_BRIGHTNESS100;
+
+ // set the brightness and push the linecount with VFD_SETFUNCTION
+ samsungvfdSetBrightness(brightness);
+
+ samsungvfd_numlines = lines;
+ samsungvfd_currline = 0;
+
+ // Initialize to default text direction (for romance languages#include "SPI_VFD.h"
+ samsungvfd_displaymode = SAMSUNGVFD_ENTRYLEFT | SAMSUNGVFD_ENTRYSHIFTDECREMENT;
+ // set the entry mode
+ samsungvfd_command(SAMSUNGVFD_ENTRYMODESET | samsungvfd_displaymode);
+
+ samsungvfd_command(SAMSUNGVFD_SETDDRAMADDR); // go to address 0
+
+ // turn the display on with no cursor or blinking default
+ samsungvfd_displaycontrol = SAMSUNGVFD_DISPLAYON;
+ samsungvfdDisplay();
+
+ samsungvfdClear();
+ samsungvfdHome();
+}
+
+/**************************************************************************/
+/* Public Methods */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+ @brief Initialises the VFD character display
+*/
+/**************************************************************************/
+void samsungvfdInit(uint8_t brightness)
+{
+ // Set all pins to output
+ gpioSetDir(SAMSUNGVFD_SIO_PORT, SAMSUNGVFD_SIO_PIN, gpioDirection_Output);
+ gpioSetDir(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, gpioDirection_Output);
+ gpioSetDir(SAMSUNGVFD_SCK_PORT, SAMSUNGVFD_SCK_PIN, gpioDirection_Output);
+
+ // Set strobe and clock pins high by default
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 1);
+ gpioSetValue(SAMSUNGVFD_SCK_PORT, SAMSUNGVFD_SCK_PIN, 1);
+
+ // Default to 2x20 display (SAMSUNG 20T202DA2JA)
+ samsungvfd_begin(20, 2, brightness);
+}
+
+/**************************************************************************/
+/*!
+ @brief Writes a single character to the VFD display
+*/
+/**************************************************************************/
+void samsungvfdWrite(uint8_t value)
+{
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 0);
+ samsungvfd_sendByte(SAMSUNGVFD_SPIDATA);
+ samsungvfd_sendByte(value);
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 1);
+}
+
+/**************************************************************************/
+/*!
+ @brief Writes a full string to the VFD display
+*/
+/**************************************************************************/
+void samsungvfdWriteString(const char * str)
+{
+ while(*str)
+ {
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 0);
+ samsungvfd_sendByte(SAMSUNGVFD_SPIDATA);
+ samsungvfd_sendByte(*str++);
+ gpioSetValue(SAMSUNGVFD_STB_PORT, SAMSUNGVFD_STB_PIN, 1);
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the display brightness
+*/
+/**************************************************************************/
+void samsungvfdSetBrightness(uint8_t brightness)
+{
+ // set the brightness (only if a valid value is passed
+ if (brightness <= SAMSUNGVFD_BRIGHTNESS25)
+ {
+ samsungvfd_displayfunction &= ~SAMSUNGVFD_BRIGHTNESS25;
+ samsungvfd_displayfunction |= brightness;
+
+ samsungvfd_command(SAMSUNGVFD_FUNCTIONSET | samsungvfd_displayfunction);
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Quickly turn the display off
+*/
+/**************************************************************************/
+void samsungvfdNoDisplay(void)
+{
+ samsungvfd_displaycontrol &= ~SAMSUNGVFD_DISPLAYON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Quickly turn the display on
+*/
+/**************************************************************************/
+void samsungvfdDisplay(void)
+{
+ samsungvfd_displaycontrol |= SAMSUNGVFD_DISPLAYON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Turns the cursor off
+*/
+/**************************************************************************/
+void samsungvfdNoCursor(void)
+{
+ samsungvfd_displaycontrol &= ~SAMSUNGVFD_CURSORON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Enables the cursor
+*/
+/**************************************************************************/
+void samsungvfdCursor(void)
+{
+ samsungvfd_displaycontrol |= SAMSUNGVFD_CURSORON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Disable cursor blinking
+*/
+/**************************************************************************/
+void samsungvfdNoBlink(void)
+{
+ samsungvfd_displaycontrol &= ~SAMSUNGVFD_BLINKON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Enable cursor blinking
+*/
+/**************************************************************************/
+void samsungvfdBlink(void)
+{
+ samsungvfd_displaycontrol |= SAMSUNGVFD_BLINKON;
+ samsungvfd_command(SAMSUNGVFD_DISPLAYCONTROL | samsungvfd_displaycontrol);
+}
+
+/**************************************************************************/
+/*!
+ @brief Scroll the display left without changing the RAM
+*/
+/**************************************************************************/
+void samsungvfdScrollDisplayLeft(void)
+{
+ samsungvfd_command(SAMSUNGVFD_CURSORSHIFT | SAMSUNGVFD_DISPLAYMOVE | SAMSUNGVFD_MOVELEFT);
+}
+
+/**************************************************************************/
+/*!
+ @brief Scroll the display right without changing the RAM
+*/
+/**************************************************************************/
+void samsungvfdScrollDisplayRight(void)
+{
+ samsungvfd_command(SAMSUNGVFD_CURSORSHIFT | SAMSUNGVFD_DISPLAYMOVE | SAMSUNGVFD_MOVERIGHT);
+}
+
+/**************************************************************************/
+/*!
+ @brief Cause text to flow left to right
+*/
+/**************************************************************************/
+void samsungvfdLeftToRight(void)
+{
+ samsungvfd_displaymode |= SAMSUNGVFD_ENTRYLEFT;
+ samsungvfd_command(SAMSUNGVFD_ENTRYMODESET | samsungvfd_displaymode);
+}
+
+/**************************************************************************/
+/*!
+ @brief Cause text to flow from right to left
+*/
+/**************************************************************************/
+void samsungvfdRightToLeft(void)
+{
+ samsungvfd_displaymode &= ~SAMSUNGVFD_ENTRYLEFT;
+ samsungvfd_command(SAMSUNGVFD_ENTRYMODESET | samsungvfd_displaymode);
+}
+
+/**************************************************************************/
+/*!
+ @brief Right justify text from the cursor
+*/
+/**************************************************************************/
+void samsungvfdAutoscroll(void)
+{
+ samsungvfd_displaymode |= SAMSUNGVFD_ENTRYSHIFTINCREMENT;
+ samsungvfd_command(SAMSUNGVFD_ENTRYMODESET | samsungvfd_displaymode);
+}
+
+/**************************************************************************/
+/*!
+ @brief Left justify text from the cursor
+*/
+/**************************************************************************/
+void samsungvfdNoAutoscroll(void)
+{
+ samsungvfd_displaymode &= ~SAMSUNGVFD_ENTRYSHIFTINCREMENT;
+ samsungvfd_command(SAMSUNGVFD_ENTRYMODESET | samsungvfd_displaymode);
+}
+
+/**************************************************************************/
+/*!
+ @brief Clears the display
+*/
+/**************************************************************************/
+void samsungvfdClear(void)
+{
+ samsungvfd_command(SAMSUNGVFD_CLEARDISPLAY); // clear display, set cursor position to zero
+ systickDelay(2); // this command takes a long time!
+}
+
+/**************************************************************************/
+/*!
+ @brief Places the cursor at 0, 0
+*/
+/**************************************************************************/
+void samsungvfdHome(void)
+{
+ samsungvfd_command(SAMSUNGVFD_RETURNHOME); // Set cursor position to zero
+ systickDelay(2); // this command takes a long time!
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the cursor to the specified row and column position
+*/
+/**************************************************************************/
+void samsungvfdSetCursor(uint8_t col, uint8_t row)
+{
+ int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+ if ( row > samsungvfd_numlines )
+ {
+ row = samsungvfd_numlines-1; // we count rows starting w/0
+ }
+
+ samsungvfd_command(SAMSUNGVFD_SETDDRAMADDR | (col + row_offsets[row]));
+}
+
--- /dev/null
+/**************************************************************************/
+/*!
+ @file samsung_20T202DA2JA.h
+ @author Original source : Limor Fried/ladyada (Adafruit Industries)
+ LPC1343 port : K. Townsend
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2012 Adafruit Industries
+ 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 __SAMSUNG_20T202DA2JA__
+#define __SAMSUNG_20T202DA2JA__
+
+#include "projectconfig.h"
+
+// Pin Definitions
+#define SAMSUNGVFD_SIO_PORT (2) // Data
+#define SAMSUNGVFD_SIO_PIN (1)
+#define SAMSUNGVFD_STB_PORT (2) // Strobe
+#define SAMSUNGVFD_STB_PIN (2)
+#define SAMSUNGVFD_SCK_PORT (2) // Clock
+#define SAMSUNGVFD_SCK_PIN (3)
+
+// Commands
+#define SAMSUNGVFD_CLEARDISPLAY 0x01
+#define SAMSUNGVFD_RETURNHOME 0x02
+#define SAMSUNGVFD_ENTRYMODESET 0x04
+#define SAMSUNGVFD_DISPLAYCONTROL 0x08
+#define SAMSUNGVFD_CURSORSHIFT 0x10
+#define SAMSUNGVFD_FUNCTIONSET 0x30
+#define SAMSUNGVFD_SETCGRAMADDR 0x40
+#define SAMSUNGVFD_SETDDRAMADDR 0x80
+
+// flags for display entry mode
+#define SAMSUNGVFD_ENTRYRIGHT 0x00
+#define SAMSUNGVFD_ENTRYLEFT 0x02
+#define SAMSUNGVFD_ENTRYSHIFTINCREMENT 0x01
+#define SAMSUNGVFD_ENTRYSHIFTDECREMENT 0x00
+
+// flags for display on/off control
+#define SAMSUNGVFD_DISPLAYON 0x04
+#define SAMSUNGVFD_DISPLAYOFF 0x00
+#define SAMSUNGVFD_CURSORON 0x02
+#define SAMSUNGVFD_CURSOROFF 0x00
+#define SAMSUNGVFD_BLINKON 0x01
+#define SAMSUNGVFD_BLINKOFF 0x00
+
+// flags for display/cursor shift
+#define SAMSUNGVFD_DISPLAYMOVE 0x08
+#define SAMSUNGVFD_CURSORMOVE 0x00
+#define SAMSUNGVFD_MOVERIGHT 0x04
+#define SAMSUNGVFD_MOVELEFT 0x00
+
+// flags for function set
+#define SAMSUNGVFD_2LINE 0x08
+#define SAMSUNGVFD_1LINE 0x00
+#define SAMSUNGVFD_BRIGHTNESS25 0x03
+#define SAMSUNGVFD_BRIGHTNESS50 0x02
+#define SAMSUNGVFD_BRIGHTNESS75 0x01
+#define SAMSUNGVFD_BRIGHTNESS100 0x00
+
+#define SAMSUNGVFD_SPICOMMAND 0xF8
+#define SAMSUNGVFD_SPIDATA 0xFA
+
+// Initialisation/Config Prototypes
+void samsungvfdInit ( uint8_t brightness );
+void samsungvfdWrite ( uint8_t value );
+void samsungvfdWriteString( const char * str );
+void samsungvfdSetBrightness ( uint8_t brightness );
+void samsungvfdNoDisplay ( void );
+void samsungvfdDisplay ( void );
+void samsungvfdNoCursor ( void );
+void samsungvfdCursor ( void );
+void samsungvfdNoBlink ( void );
+void samsungvfdBlink ( void );
+void samsungvfdScrollDisplayLeft ( void );
+void samsungvfdScrollDisplayRight ( void );
+void samsungvfdLeftToRight ( void );
+void samsungvfdRightToLeft ( void );
+void samsungvfdAutoscroll ( void );
+void samsungvfdNoAutoscroll ( void );
+void samsungvfdClear ( void );
+void samsungvfdHome ( void );
+void samsungvfdSetCursor ( uint8_t col, uint8_t row );
+
+#endif
/*=========================================================================*/
+/*=========================================================================
+ ADC
+ -----------------------------------------------------------------------
+
+ ADC_AVERAGING_ENABLE To get better results, the ADC code can take
+ a number of samples and return the average
+ value. This is slower, but can give more
+ accurate results caused of single-reading
+ peaks and dips.
+ To enable average, set ADC_AVERAGING_ENABLE
+ to a non-zero value.
+ ADC_AVERAGING_SAMPLES The number of ADC samples to read and
+ average if ADC averaging is enabled.
+
+ -----------------------------------------------------------------------*/
+ #ifdef CFG_BRD_LPC1343_REFDESIGN
+ #define ADC_AVERAGING_ENABLE (1)
+ #define ADC_AVERAGING_SAMPLES (5)
+ #endif
+
+ #ifdef CFG_BRD_LPC1343_REFDESIGN_MINIMAL
+ #define ADC_AVERAGING_ENABLE (1)
+ #define ADC_AVERAGING_SAMPLES (5)
+ #endif
+
+ #if defined CFG_BRD_LPC1343_TFTLCDSTANDALONE_USB || defined CFG_BRD_LPC1343_TFTLCDSTANDALONE_UART
+ #define ADC_AVERAGING_ENABLE (0)
+ #define ADC_AVERAGING_SAMPLES (5)
+ #endif
+
+ #ifdef CFG_BRD_LPC1343_802154USBSTICK
+ #define ADC_AVERAGING_ENABLE (0)
+ #define ADC_AVERAGING_SAMPLES (5)
+ #endif
+
+ #ifdef CFG_BRD_LPC1343_OLIMEX_P
+ #define ADC_AVERAGING_ENABLE (0)
+ #define ADC_AVERAGING_SAMPLES (5)
+ #endif
+/*=========================================================================*/
+
+
/*=========================================================================
ON-BOARD LED
-----------------------------------------------------------------------
#endif
#endif
+#if ADC_AVERAGING_ENABLE && ADC_AVERAGING_SAMPLES < 1
+ #error "ADC_AVERAGING_SAMPLES must be 1 or higher when ADC averaging is enabled"
+#endif
+
#endif
#include "core/cpu/cpu.h"
#include "core/pmu/pmu.h"
-#include "core/adc/adc.h"
#ifdef CFG_PRINTF_UART
#include "core/uart/uart.h"
--- /dev/null
+This test program will read 1K samples from the ADC,
+and send the results in CSV format out via USB CDC.
+
+The test results can be pasted into Excel and analyzed
+to better understand the ADC performance.
+
+There appears to be a couple LSB of variation on the ADC
+of the LPC1343 Reference Design, including some fairly
+large one-off peaks and valleys.
+
+As a result of these tests, and additional flag was added
+to the code base to enable the ADC code to optionally take
+a number of readings and return an average result, which
+helps reduce the effect of individual peaks or dips in the
+ADC.
+
+Results of the tests with and without averaging can be
+seen in the included excel spreadsheets, showing min, max
+and stddev for the range of data captured.
+
+As was expected, the ADC seems to perform better towards the
+middle of the range than on the lower end.
\ No newline at end of file
--- /dev/null
+/**************************************************************************/
+/*!
+ @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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "projectconfig.h"
+#include "sysinit.h"
+
+#include "core/gpio/gpio.h"
+#include "core/adc/adc.h"
+#include "core/systick/systick.h"
+
+// ADC buffer
+uint16_t buffer[1024][2];
+
+/**************************************************************************/
+/*!
+ Main program entry point. After reset, normal code execution will
+ begin here.
+*/
+/**************************************************************************/
+int main(void)
+{
+ // Configure cpu and mandatory peripherals
+ systemInit();
+
+ // Initialize the ADC
+ adcInit();
+
+ uint32_t currentTick, lastTick, i;
+ i = currentTick = lastTick = 0;
+
+ // Clear the ADC buffer
+ memset(&buffer, 0, sizeof(buffer));
+
+ // Turn on LED during ADC read
+ gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON);
+
+ // Sample ADC once per millisecond and store it in the buffer
+ while (i < 1024)
+ {
+ currentTick = systickGetTicks();
+ if (currentTick != lastTick)
+ {
+ lastTick = currentTick;
+ buffer[i][0] = (uint16_t)(currentTick & 0xFFFF);
+ buffer[i][1] = adcRead(0); // ADC Results
+ i++;
+ }
+ }
+
+ // Turn LED off
+ gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF);
+
+ // Brief delay before spitting results out via USB CDC
+ systickDelay(3000);
+
+ // Print results out in CSV format
+ i = 0;
+ while (i < 1024)
+ {
+ printf("%d, %d %s", buffer[i][0], buffer[i][1], CFG_PRINTF_NEWLINE);
+ i++;
+ }
+
+ // Wait forever
+ while(1)
+ {
+ }
+
+ return 0;
+}