Stripped down version of microbuilder.eu lpc1343codebase
I hope I didn't break anything too hard.
This commit is contained in:
commit
0c23bf065d
|
@ -0,0 +1,108 @@
|
|||
##########################################################################
|
||||
# User configuration and firmware specific object files
|
||||
##########################################################################
|
||||
|
||||
# The target, flash and ram of the LPC1xxx microprocessor.
|
||||
# Use for the target the value: LPC11xx, LPC13xx or LPC17xx
|
||||
TARGET = LPC13xx
|
||||
FLASH = 32K
|
||||
SRAM = 8K
|
||||
|
||||
# For USB HID support the LPC134x reserves 384 bytes from the sram,
|
||||
# if you don't want to use the USB features, just use 0 here.
|
||||
SRAM_USB = 384
|
||||
|
||||
VPATH =
|
||||
OBJS = main.o
|
||||
|
||||
##########################################################################
|
||||
# Project-specific files
|
||||
##########################################################################
|
||||
|
||||
VPATH +=
|
||||
OBJS +=
|
||||
LIBS += core/libcore.a lcd/libfont.a
|
||||
|
||||
##########################################################################
|
||||
# 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 = tools/lpcrc
|
||||
|
||||
##########################################################################
|
||||
# GNU GCC compiler flags
|
||||
##########################################################################
|
||||
ROOT_PATH = .
|
||||
INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/core
|
||||
|
||||
##########################################################################
|
||||
# Startup files
|
||||
##########################################################################
|
||||
|
||||
LD_PATH = lpc1xxx
|
||||
LD_SCRIPT = $(LD_PATH)/linkscript.ld
|
||||
LD_TEMP = $(LD_PATH)/memory.ld
|
||||
|
||||
ifeq (LPC11xx,$(TARGET))
|
||||
CORTEX_TYPE=m0
|
||||
else
|
||||
CORTEX_TYPE=m3
|
||||
endif
|
||||
|
||||
CPU_TYPE = cortex-$(CORTEX_TYPE)
|
||||
VPATH += lpc1xxx
|
||||
OBJS += $(TARGET)_handlers.o LPC1xxx_startup.o
|
||||
|
||||
##########################################################################
|
||||
# Compiler settings, parameters and flags
|
||||
##########################################################################
|
||||
|
||||
CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin
|
||||
LDFLAGS = -nostartfiles -mthumb -mcpu=$(CPU_TYPE) -Wl,--gc-sections
|
||||
LDLIBS = -lm
|
||||
LDLIBS += -Lcore -lcore
|
||||
LDLIBS += -Llcd -lfont
|
||||
OCFLAGS = --strip-unneeded
|
||||
|
||||
all: firmware
|
||||
|
||||
%.o : %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
core/libcore.a: core/projectconfig.h
|
||||
cd core && $(MAKE)
|
||||
|
||||
lcd/libfont.a:
|
||||
cd lcd && $(MAKE)
|
||||
|
||||
tools/lpcrc:
|
||||
cd tools && $(MAKE)
|
||||
|
||||
firmware: $(OBJS) $(SYS_OBJS) $(LIBS) $(LPCRC)
|
||||
-@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
|
||||
-@echo ""
|
||||
$(LPCRC) $(OUTFILE).bin
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex
|
||||
@cd core && $(MAKE) clean
|
||||
@cd tools && $(MAKE) clean
|
||||
@cd lcd && $(MAKE) clean
|
|
@ -0,0 +1,85 @@
|
|||
##########################################################################
|
||||
# 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
|
||||
|
||||
OBJS = sysinit.o
|
||||
OBJS += adc/adc.o
|
||||
#OBJS += cmd/cmd.o
|
||||
OBJS += cpu/cpu.o
|
||||
OBJS += gpio/gpio.o
|
||||
OBJS += i2c/i2c.o
|
||||
OBJS += iap/iap.o
|
||||
OBJS += libc/ctype.o
|
||||
OBJS += libc/stdio.o
|
||||
OBJS += libc/string.o
|
||||
OBJS += pmu/pmu.o
|
||||
#OBJS += pwm/pwm.o
|
||||
OBJS += ssp/ssp.o
|
||||
OBJS += systick/systick.o
|
||||
OBJS += timer16/timer16.o
|
||||
OBJS += timer32/timer32.o
|
||||
#OBJS += uart/uart.o
|
||||
#OBJS += uart/uart_buf.o
|
||||
#OBJS += usbcdc/cdcuser.o
|
||||
#OBJS += usbcdc/cdc_buf.o
|
||||
#OBJS += usbcdc/usbcore.o
|
||||
#OBJS += usbcdc/usbdesc.o
|
||||
#OBJS += usbcdc/usbhw.o
|
||||
#OBJS += usbcdc/usbuser.o
|
||||
#OBJS += usbhid-rom/usbconfig.o
|
||||
#OBJS += usbhid-rom/usbhid.o
|
||||
OBJS += wdt/wdt.o
|
||||
|
||||
##########################################################################
|
||||
# GNU GCC compiler prefix and location
|
||||
##########################################################################
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
AS = $(CROSS_COMPILE)gcc
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
OBJDUMP = $(CROSS_COMPILE)objdump
|
||||
OUTFILE = firmware
|
||||
|
||||
##########################################################################
|
||||
# GNU GCC compiler flags
|
||||
##########################################################################
|
||||
ROOT_PATH = .
|
||||
INCLUDE_PATHS = -I$(ROOT_PATH) -I..
|
||||
|
||||
##########################################################################
|
||||
# Startup files
|
||||
##########################################################################
|
||||
|
||||
ifeq (LPC11xx,$(TARGET))
|
||||
CORTEX_TYPE=m0
|
||||
else
|
||||
CORTEX_TYPE=m3
|
||||
endif
|
||||
|
||||
CPU_TYPE = cortex-$(CORTEX_TYPE)
|
||||
|
||||
##########################################################################
|
||||
# Compiler settings, parameters and flags
|
||||
##########################################################################
|
||||
|
||||
CFLAGS = -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -fno-builtin
|
||||
LDFLAGS = -nostartfiles -mthumb -mcpu=$(CPU_TYPE) -Wl,--gc-sections
|
||||
|
||||
all: libcore.a
|
||||
|
||||
libcore.a: $(OBJS)
|
||||
$(AR) rcs libcore.a $(OBJS)
|
||||
|
||||
%.o : %.c projectconfig.h
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) libcore.a
|
|
@ -0,0 +1,228 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file adc.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section Description
|
||||
|
||||
SW-based single-channel A/D conversion. If you wish to convert
|
||||
multiple ADC channels simultaneously, this code will need to be
|
||||
modified to work in BURST mode.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/adc/adc.h"
|
||||
|
||||
void main (void)
|
||||
{
|
||||
cpuInit();
|
||||
adcInit();
|
||||
|
||||
uint32_t results = 0;
|
||||
while(1)
|
||||
{
|
||||
// Get A/D conversion results from A/D channel 0
|
||||
results = adcRead(0);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
static bool _adcInitialised = false;
|
||||
static uint8_t _adcLastChannel = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Returns the conversion results on the specified ADC channel.
|
||||
|
||||
This function will manually start an A/D conversion on a single
|
||||
channel and return the results.
|
||||
|
||||
@param[in] channelNum
|
||||
The A/D channel [0..7] that will be used during the A/D
|
||||
conversion. (Note that only A/D channel's 0..3 are
|
||||
configured by default in adcInit.)
|
||||
|
||||
@return 0 if an overrun error occured, otherwise a 10-bit value
|
||||
containing the A/D conversion results.
|
||||
@warning Only AD channels 0..3 are configured for A/D in adcInit.
|
||||
If you wish to use A/D pins 4..7 they will also need to
|
||||
be added to the adcInit function.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t adcRead (uint8_t channelNum)
|
||||
{
|
||||
if (!_adcInitialised) adcInit();
|
||||
|
||||
uint32_t regVal, adcData;
|
||||
|
||||
/* make sure that channel number is 0..7 */
|
||||
if ( channelNum >= 8 )
|
||||
{
|
||||
// ToDo: Change this to throw an exception back
|
||||
channelNum = 0;
|
||||
}
|
||||
|
||||
/* Deselect all channels */
|
||||
ADC_AD0CR &= ~ADC_AD0CR_SEL_MASK;
|
||||
|
||||
/* Start converting now on the appropriate channel */
|
||||
ADC_AD0CR |= ADC_AD0CR_START_STARTNOW | (1 << channelNum);
|
||||
|
||||
/* wait until end of A/D convert */
|
||||
while ( 1 )
|
||||
{
|
||||
// Get data register results for the requested channel
|
||||
switch (channelNum)
|
||||
{
|
||||
case 0:
|
||||
regVal = (*(pREG32(ADC_AD0DR0)));
|
||||
break;
|
||||
case 1:
|
||||
regVal = (*(pREG32(ADC_AD0DR1)));
|
||||
break;
|
||||
case 2:
|
||||
regVal = (*(pREG32(ADC_AD0DR2)));
|
||||
break;
|
||||
case 3:
|
||||
regVal = (*(pREG32(ADC_AD0DR3)));
|
||||
break;
|
||||
case 4:
|
||||
regVal = (*(pREG32(ADC_AD0DR4)));
|
||||
break;
|
||||
case 5:
|
||||
regVal = (*(pREG32(ADC_AD0DR5)));
|
||||
break;
|
||||
case 6:
|
||||
regVal = (*(pREG32(ADC_AD0DR6)));
|
||||
break;
|
||||
case 7:
|
||||
regVal = (*(pREG32(ADC_AD0DR7)));
|
||||
break;
|
||||
default:
|
||||
regVal = (*(pREG32(ADC_AD0DR0)));
|
||||
break;
|
||||
}
|
||||
|
||||
/* read result of A/D conversion */
|
||||
if (regVal & ADC_DR_DONE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* stop ADC */
|
||||
ADC_AD0CR &= ~ADC_AD0CR_START_MASK;
|
||||
|
||||
/* return 0 if an overrun occurred */
|
||||
if ( regVal & ADC_DR_OVERRUN )
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* return conversion results */
|
||||
adcData = (regVal >> 6) & 0x3FF;
|
||||
return (adcData);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the A/D converter and configures channels 0..3
|
||||
for 10-bit, SW-controlled A/D conversion.
|
||||
|
||||
@return Nothing
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void adcInit (void)
|
||||
{
|
||||
/* Disable Power down bit to the ADC block. */
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_ADC);
|
||||
|
||||
/* Enable AHB clock to the ADC. */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_ADC);
|
||||
|
||||
/* Digital pins need to have the 'analog' bit set in addition
|
||||
to changing their pin function */
|
||||
|
||||
/* Set AD0 to analog input */
|
||||
IOCON_JTAG_TDI_PIO0_11 &= ~(IOCON_JTAG_TDI_PIO0_11_ADMODE_MASK |
|
||||
IOCON_JTAG_TDI_PIO0_11_FUNC_MASK |
|
||||
IOCON_JTAG_TDI_PIO0_11_MODE_MASK);
|
||||
IOCON_JTAG_TDI_PIO0_11 |= (IOCON_JTAG_TDI_PIO0_11_FUNC_AD0 &
|
||||
IOCON_JTAG_TDI_PIO0_11_ADMODE_ANALOG);
|
||||
|
||||
/* Set AD1 to analog input */
|
||||
IOCON_JTAG_TMS_PIO1_0 &= ~(IOCON_JTAG_TMS_PIO1_0_ADMODE_MASK |
|
||||
IOCON_JTAG_TMS_PIO1_0_FUNC_MASK |
|
||||
IOCON_JTAG_TMS_PIO1_0_MODE_MASK);
|
||||
IOCON_JTAG_TMS_PIO1_0 |= (IOCON_JTAG_TMS_PIO1_0_FUNC_AD1 &
|
||||
IOCON_JTAG_TMS_PIO1_0_ADMODE_ANALOG);
|
||||
|
||||
/* Set AD2 to analog input */
|
||||
IOCON_JTAG_TDO_PIO1_1 &= ~(IOCON_JTAG_TDO_PIO1_1_ADMODE_MASK |
|
||||
IOCON_JTAG_TDO_PIO1_1_FUNC_MASK |
|
||||
IOCON_JTAG_TDO_PIO1_1_MODE_MASK);
|
||||
IOCON_JTAG_TDO_PIO1_1 |= (IOCON_JTAG_TDO_PIO1_1_FUNC_AD2 &
|
||||
IOCON_JTAG_TDO_PIO1_1_ADMODE_ANALOG);
|
||||
|
||||
/* Set AD3 to analog input */
|
||||
IOCON_JTAG_nTRST_PIO1_2 &= ~(IOCON_JTAG_nTRST_PIO1_2_ADMODE_MASK |
|
||||
IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK |
|
||||
IOCON_JTAG_nTRST_PIO1_2_MODE_MASK);
|
||||
IOCON_JTAG_nTRST_PIO1_2 |= (IOCON_JTAG_nTRST_PIO1_2_FUNC_AD3 &
|
||||
IOCON_JTAG_nTRST_PIO1_2_ADMODE_ANALOG);
|
||||
|
||||
/* Note that in SW mode only one channel can be selected at a time (AD0 in this case)
|
||||
To select multiple channels, ADC_AD0CR_BURST_HWSCANMODE must be used */
|
||||
ADC_AD0CR = (ADC_AD0CR_SEL_AD0 | /* SEL=1,select channel 0 on ADC0 */
|
||||
(((CFG_CPU_CCLK / SCB_SYSAHBCLKDIV) / 1000000 - 1 ) << 8) | /* CLKDIV = Fpclk / 1000000 - 1 */
|
||||
ADC_AD0CR_BURST_SWMODE | /* BURST = 0, no BURST, software controlled */
|
||||
ADC_AD0CR_CLKS_10BITS | /* CLKS = 0, 11 clocks/10 bits */
|
||||
ADC_AD0CR_START_NOSTART | /* START = 0 A/D conversion stops */
|
||||
ADC_AD0CR_EDGE_RISING); /* EDGE = 0 (CAP/MAT signal falling, trigger A/D conversion) */
|
||||
|
||||
/* Set initialisation flag */
|
||||
_adcInitialised = true;
|
||||
|
||||
/* Set last channel flag to 0 (initialised above) */
|
||||
_adcLastChannel = 0;
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file adc.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _ADC_H_
|
||||
#define _ADC_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
uint32_t adcRead (uint8_t channelNum);
|
||||
void adcInit (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,296 @@
|
|||
/*******************************************************************
|
||||
Copyright (C) 2009 FreakLabs
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Originally written by Christopher Wang aka Akiba.
|
||||
Please post support questions to the FreakLabs forum.
|
||||
*******************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file cmd.c
|
||||
@author Christopher Wang (Freaklabs)
|
||||
Modified by: K. Townsend (microBuilder.eu)
|
||||
@date 19 May 2010
|
||||
|
||||
Original code taken from the FreakUSB Open Source USB Device Stack
|
||||
http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
|
||||
|
||||
If it works well, you can thank Akiba at Freaklabs. If it fails
|
||||
miserably, you can blame me (since parts of it it were rather
|
||||
ungraciously modified). :-)
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "project/cmd_tbl.h"
|
||||
|
||||
#ifdef CFG_PRINTF_UART
|
||||
#include "core/uart/uart.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_PRINTF_USBCDC
|
||||
#include "core/usbcdc/cdcuser.h"
|
||||
static char usbcdcBuf [32];
|
||||
#endif
|
||||
|
||||
#if CFG_INTERFACE_ENABLEIRQ == 1
|
||||
#include "core/gpio/gpio.h"
|
||||
#endif
|
||||
|
||||
static uint8_t msg[CFG_INTERFACE_MAXMSGSIZE];
|
||||
static uint8_t *msg_ptr;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Polls the relevant incoming message queue to see if anything
|
||||
is waiting to be processed.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cmdPoll()
|
||||
{
|
||||
#if defined CFG_PRINTF_UART
|
||||
while (uartRxBufferDataPending())
|
||||
{
|
||||
uint8_t c = uartRxBufferRead();
|
||||
cmdRx(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined CFG_PRINTF_USBCDC
|
||||
int numBytesToRead, numBytesRead, numAvailByte;
|
||||
|
||||
CDC_OutBufAvailChar (&numAvailByte);
|
||||
if (numAvailByte > 0)
|
||||
{
|
||||
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
|
||||
numBytesRead = CDC_RdOutBuf (&usbcdcBuf[0], &numBytesToRead);
|
||||
int i;
|
||||
for (i = 0; i < numBytesRead; i++)
|
||||
{
|
||||
cmdRx(usbcdcBuf[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Handles a single incoming character. If a new line is
|
||||
detected, the entire command will be passed to the command
|
||||
parser. If a text character is detected, it will be added to
|
||||
the message buffer until a new line is detected (up to the
|
||||
maximum queue size, CFG_INTERFACE_MAXMSGSIZE).
|
||||
|
||||
@param[in] c
|
||||
The character to parse.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cmdRx(uint8_t c)
|
||||
{
|
||||
// read out the data in the buffer and echo it back to the host.
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
// terminate the msg and reset the msg ptr. then send
|
||||
// it to the handler for processing.
|
||||
*msg_ptr = '\0';
|
||||
#if CFG_INTERFACE_SILENTMODE == 0
|
||||
printf("%s", CFG_PRINTF_NEWLINE);
|
||||
#endif
|
||||
cmdParse((char *)msg);
|
||||
msg_ptr = msg;
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
#if CFG_INTERFACE_SILENTMODE == 0
|
||||
printf("%c",c);
|
||||
#endif
|
||||
if (msg_ptr > msg)
|
||||
{
|
||||
msg_ptr--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#if CFG_INTERFACE_SILENTMODE == 0
|
||||
printf("%c",c);
|
||||
#endif
|
||||
*msg_ptr++ = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Displays the command prompt. The text that appears is defined
|
||||
in projectconfig.h.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static void cmdMenu()
|
||||
{
|
||||
#if CFG_INTERFACE_SILENTMODE == 0
|
||||
printf(CFG_PRINTF_NEWLINE);
|
||||
printf(CFG_INTERFACE_PROMPT);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Parse the command line. This function tokenizes the command
|
||||
input, then searches for the command table entry associated
|
||||
with the commmand. Once found, it will jump to the
|
||||
corresponding function.
|
||||
|
||||
@param[in] cmd
|
||||
The entire command string to be parsed
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cmdParse(char *cmd)
|
||||
{
|
||||
size_t argc, i = 0;
|
||||
char *argv[30];
|
||||
|
||||
argv[i] = strtok(cmd, " ");
|
||||
do
|
||||
{
|
||||
argv[++i] = strtok(NULL, " ");
|
||||
} while ((i < 30) && (argv[i] != NULL));
|
||||
|
||||
argc = i;
|
||||
for (i=0; i < CMD_COUNT; i++)
|
||||
{
|
||||
if (!strcmp(argv[0], cmd_tbl[i].command))
|
||||
{
|
||||
if ((argc == 2) && !strcmp (argv [1], "?"))
|
||||
{
|
||||
// Display parameter help menu on 'command ?'
|
||||
printf ("%s%s%s", cmd_tbl[i].description, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
|
||||
printf ("%s%s", cmd_tbl[i].parameters, CFG_PRINTF_NEWLINE);
|
||||
}
|
||||
else if ((argc - 1) < cmd_tbl[i].minArgs)
|
||||
{
|
||||
// Too few arguments supplied
|
||||
printf ("Too few arguments (%d expected)%s", cmd_tbl[i].minArgs, CFG_PRINTF_NEWLINE);
|
||||
printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
|
||||
}
|
||||
else if ((argc - 1) > cmd_tbl[i].maxArgs)
|
||||
{
|
||||
// Too many arguments supplied
|
||||
printf ("Too many arguments (%d maximum)%s", cmd_tbl[i].maxArgs, CFG_PRINTF_NEWLINE);
|
||||
printf ("%sType '%s ?' for more information%s%s", CFG_PRINTF_NEWLINE, cmd_tbl[i].command, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CFG_INTERFACE_ENABLEIRQ != 0
|
||||
// Set the IRQ pin high at start of a command
|
||||
gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1);
|
||||
#endif
|
||||
// Dispatch command to the appropriate function
|
||||
cmd_tbl[i].func(argc - 1, &argv [1]);
|
||||
#if CFG_INTERFACE_ENABLEIRQ != 0
|
||||
// Set the IRQ pin low to signal the end of a command
|
||||
gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Refresh the command prompt
|
||||
cmdMenu();
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("Command not recognized: '%s'%s%s", cmd, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
|
||||
#if CFG_INTERFACE_SILENTMODE == 0
|
||||
printf("Type '?' for a list of all available commands%s", CFG_PRINTF_NEWLINE);
|
||||
#endif
|
||||
|
||||
cmdMenu();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the command line using the appropriate interface
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cmdInit()
|
||||
{
|
||||
#if defined CFG_INTERFACE && defined CFG_INTERFACE_UART
|
||||
// Check if UART is already initialised
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
if (!pcb->initialised)
|
||||
{
|
||||
uartInit(CFG_UART_BAUDRATE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_INTERFACE_ENABLEIRQ != 0
|
||||
// Set IRQ pin as output
|
||||
gpioSetDir(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, gpioDirection_Output);
|
||||
gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1);
|
||||
#endif
|
||||
|
||||
// init the msg ptr
|
||||
msg_ptr = msg;
|
||||
|
||||
// Show the menu
|
||||
cmdMenu();
|
||||
|
||||
// Set the IRQ pin low by default
|
||||
#if CFG_INTERFACE_ENABLEIRQ != 0
|
||||
gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
'help' command handler
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cmd_help(uint8_t argc, char **argv)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
printf("Command Description%s", CFG_PRINTF_NEWLINE);
|
||||
printf("------- -----------%s", CFG_PRINTF_NEWLINE);
|
||||
|
||||
// Display full command list
|
||||
for (i=0; i < CMD_COUNT; i++)
|
||||
{
|
||||
if (!cmd_tbl[i].hidden)
|
||||
{
|
||||
printf ("%-10s %s%s", cmd_tbl[i].command, cmd_tbl[i].description, CFG_PRINTF_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%sCommand parameters can be seen by entering: <command-name> ?%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file cmd.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __CMD_H__
|
||||
#define __CMD_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *command;
|
||||
uint8_t minArgs;
|
||||
uint8_t maxArgs;
|
||||
uint8_t hidden;
|
||||
void (*func)(uint8_t argc, char **argv);
|
||||
const char *description;
|
||||
const char *parameters;
|
||||
} cmd_t;
|
||||
|
||||
void cmdPoll();
|
||||
void cmdRx(uint8_t c);
|
||||
void cmdParse(char *cmd);
|
||||
void cmdInit();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,169 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file cpu.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Initialises the CPU and any core clocks. By default, the core clock
|
||||
is set to run at 72MHz. In order to reduce power consumption all pins
|
||||
are set to GPIO and input by cpuInit.
|
||||
|
||||
@section EXAMPLE
|
||||
@code
|
||||
#include "lpc134x.h"
|
||||
#include "core/cpu/cpu.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
// Initialise the CPU and setup the PLL
|
||||
cpuInit();
|
||||
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "core/gpio/gpio.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures the main clock/PLL
|
||||
|
||||
The speed at which the MCU operates is set here using the SCB_PLLCTRL
|
||||
register, and the SCB_PLLCLKSEL register can be used to select which
|
||||
oscillator to use to generate the system clocks (the internal 12MHz
|
||||
oscillator or an external crystal).
|
||||
|
||||
@param[in] multiplier
|
||||
The PLL multiplier
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cpuPllSetup (cpuMultiplier_t multiplier)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
// Power up system oscillator
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSOSC_MASK);
|
||||
|
||||
// Setup the crystal input (bypass disabled, 1-20MHz crystal)
|
||||
SCB_SYSOSCCTRL = (SCB_SYSOSCCTRL_BYPASS_DISABLED | SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ);
|
||||
|
||||
for (i = 0; i < 200; i++)
|
||||
{
|
||||
__asm volatile ("NOP");
|
||||
}
|
||||
|
||||
// Configure PLL
|
||||
SCB_PLLCLKSEL = SCB_CLKSEL_SOURCE_MAINOSC; // Select external crystal as PLL clock source
|
||||
SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source
|
||||
SCB_PLLCLKUEN = SCB_PLLCLKUEN_DISABLE; // Toggle update register once
|
||||
SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source again
|
||||
|
||||
// Wait until the clock is updated
|
||||
while (!(SCB_PLLCLKUEN & SCB_PLLCLKUEN_UPDATE));
|
||||
|
||||
// Set clock speed
|
||||
switch (multiplier)
|
||||
{
|
||||
case CPU_MULTIPLIER_2:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_2 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
case CPU_MULTIPLIER_3:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_3 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
case CPU_MULTIPLIER_4:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_4 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
case CPU_MULTIPLIER_5:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_5 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
case CPU_MULTIPLIER_6:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_6 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
case CPU_MULTIPLIER_1:
|
||||
default:
|
||||
SCB_PLLCTRL = (SCB_PLLCTRL_MULT_1 | (1 << SCB_PLLCTRL_DIV_BIT));
|
||||
break;
|
||||
}
|
||||
|
||||
// Enable system PLL
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSPLL_MASK);
|
||||
|
||||
// Wait for PLL to lock
|
||||
while (!(SCB_PLLSTAT & SCB_PLLSTAT_LOCK));
|
||||
|
||||
// Setup main clock (use PLL output)
|
||||
SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT;
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE;
|
||||
|
||||
// Wait until the clock is updated
|
||||
while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE));
|
||||
|
||||
// Disable USB clock by default (enabled in USB code)
|
||||
SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPAD_PD); // Power-down USB PHY
|
||||
SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPLL_PD); // Power-down USB PLL
|
||||
|
||||
// Set system AHB clock
|
||||
SCB_SYSAHBCLKDIV = SCB_SYSAHBCLKDIV_DIV1;
|
||||
|
||||
// Enabled IOCON clock for I/O related peripherals
|
||||
SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_IOCON;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the CPU, setting up the PLL, etc.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cpuInit (void)
|
||||
{
|
||||
gpioInit();
|
||||
|
||||
// Set all GPIO pins to input by default
|
||||
GPIO_GPIO0DIR &= ~(GPIO_IO_ALL);
|
||||
GPIO_GPIO1DIR &= ~(GPIO_IO_ALL);
|
||||
GPIO_GPIO2DIR &= ~(GPIO_IO_ALL);
|
||||
GPIO_GPIO3DIR &= ~(GPIO_IO_ALL);
|
||||
|
||||
// Setup PLL (etc.)
|
||||
cpuPllSetup(CPU_MULTIPLIER_6);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file cpu.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _CPU_H_
|
||||
#define _CPU_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
// Macro to initialise, reset and enable the cycle counter.
|
||||
// This can be used for rough timing and performance tests
|
||||
// by resetting the cycle counter before a function, and
|
||||
// then reading the value after with "int count = DWT_CYCCNT"
|
||||
//
|
||||
// CPU_RESET_CYCLECOUNTER;
|
||||
// ... do something
|
||||
// int count = DWT_CYCCNT;
|
||||
//
|
||||
#define CPU_RESET_CYCLECOUNTER do { SCB_DEMCR = SCB_DEMCR | 0x01000000; \
|
||||
DWT_CYCCNT = 0; \
|
||||
DWT_CTRL = DWT_CTRL | 1 ; } while(0)
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Indicates the value for the PLL multiplier
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum
|
||||
{
|
||||
CPU_MULTIPLIER_1 = 0,
|
||||
CPU_MULTIPLIER_2,
|
||||
CPU_MULTIPLIER_3,
|
||||
CPU_MULTIPLIER_4,
|
||||
CPU_MULTIPLIER_5,
|
||||
CPU_MULTIPLIER_6
|
||||
}
|
||||
cpuMultiplier_t;
|
||||
|
||||
void cpuPllSetup (cpuMultiplier_t multiplier);
|
||||
void cpuInit (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,550 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file gpio.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Controls the general purpose digital IO.
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
#ifdef CFG_CHIBI
|
||||
#include "drivers/chibi/chb_drvr.h"
|
||||
volatile uint32_t chibi_counter = 0;
|
||||
#endif
|
||||
|
||||
static bool _gpioInitialised = false;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief IRQ Handler for GPIO port 0 (currently checks pin 0.1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void PIOINT0_IRQHandler(void)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
regVal = gpioIntStatus(0, 1);
|
||||
if (regVal)
|
||||
{
|
||||
gpioIntClear(0, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief IRQ Handler for GPIO port 1 (currently checks pin 1.1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void PIOINT1_IRQHandler(void)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
#ifdef CFG_CHIBI
|
||||
// Check for interrupt on 1.8
|
||||
regVal = gpioIntStatus(1, 8);
|
||||
if (regVal)
|
||||
{
|
||||
chibi_counter++;
|
||||
chb_ISR_Handler();
|
||||
gpioIntClear(1, 8);
|
||||
}
|
||||
#else
|
||||
regVal = gpioIntStatus(1, 1);
|
||||
if ( regVal )
|
||||
{
|
||||
gpioIntClear(1, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief IRQ Handler for GPIO port 2 (currently checks pin 2.1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void PIOINT2_IRQHandler(void)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
regVal = gpioIntStatus(2, 1);
|
||||
if ( regVal )
|
||||
{
|
||||
gpioIntClear(2, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief IRQ Handler for GPIO port 3 (currently checks pin 3.1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void PIOINT3_IRQHandler(void)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
regVal = gpioIntStatus(3, 1);
|
||||
if ( regVal )
|
||||
{
|
||||
gpioIntClear(3, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises GPIO and enables the GPIO interrupt
|
||||
handler for all GPIO ports.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioInit (void)
|
||||
{
|
||||
/* Enable AHB clock to the GPIO domain. */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_GPIO);
|
||||
|
||||
/* Set up NVIC when I/O pins are configured as external interrupts. */
|
||||
NVIC_EnableIRQ(EINT0_IRQn);
|
||||
NVIC_EnableIRQ(EINT1_IRQn);
|
||||
NVIC_EnableIRQ(EINT2_IRQn);
|
||||
NVIC_EnableIRQ(EINT3_IRQn);
|
||||
|
||||
/* Set initialisation flag */
|
||||
_gpioInitialised = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the direction (input/output) for a specific port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..11)
|
||||
@param[in] dir
|
||||
The pin direction (gpioDirection_Input or
|
||||
gpioDirection_Output)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioSetDir (uint32_t portNum, uint32_t bitPos, gpioDirection_t dir)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
// Get the appropriate register (handled this way to optimise code size)
|
||||
REG32 *gpiodir = &GPIO_GPIO0DIR;
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
gpiodir = &GPIO_GPIO0DIR;
|
||||
break;
|
||||
case 1:
|
||||
gpiodir = &GPIO_GPIO1DIR;
|
||||
break;
|
||||
case 2:
|
||||
gpiodir = &GPIO_GPIO2DIR;
|
||||
break;
|
||||
case 3:
|
||||
gpiodir = &GPIO_GPIO3DIR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Toggle dir
|
||||
dir == gpioDirection_Output ? (*gpiodir |= (1 << bitPos)) : (*gpiodir &= ~(1 << bitPos));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the value for a specific port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
|
||||
@return The current value for the specified port pin (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t gpioGetValue (uint32_t portNum, uint32_t bitPos)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
value = (GPIO_GPIO0DATA & (1 << bitPos)) ? 1 : 0;
|
||||
break;
|
||||
case 1:
|
||||
value = (GPIO_GPIO1DATA & (1 << bitPos)) ? 1 : 0;
|
||||
break;
|
||||
case 2:
|
||||
value = (GPIO_GPIO2DATA & (1 << bitPos)) ? 1 : 0;
|
||||
break;
|
||||
case 3:
|
||||
value = (GPIO_GPIO3DATA & (1 << bitPos)) ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the value for a specific port pin (only relevant when a
|
||||
pin is configured as output).
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
@param[in] bitValue
|
||||
The value to set for the specified bit (0..1). 0 will set
|
||||
the pin low and 1 will set the pin high.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioSetValue (uint32_t portNum, uint32_t bitPos, uint32_t bitVal)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
// Get the appropriate register (handled this way to optimise code size)
|
||||
REG32 *gpiodata = &GPIO_GPIO0DATA;
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
gpiodata = &GPIO_GPIO0DATA;
|
||||
break;
|
||||
case 1:
|
||||
gpiodata = &GPIO_GPIO1DATA;
|
||||
break;
|
||||
case 2:
|
||||
gpiodata = &GPIO_GPIO2DATA;
|
||||
break;
|
||||
case 3:
|
||||
gpiodata = &GPIO_GPIO3DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
// Toggle value
|
||||
bitVal == 1 ? (*gpiodata |= (1 << bitPos)) : (*gpiodata &= ~(1 << bitPos));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the interrupt sense, event, etc.
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
@param[in] sense
|
||||
Whether the interrupt should be configured as edge or level
|
||||
sensitive.
|
||||
@param[in] edge
|
||||
Whether one edge or both trigger an interrupt.
|
||||
@param[in] event
|
||||
Whether the rising or the falling edge (high or low)
|
||||
should be used to trigger the interrupt.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Initialise gpio
|
||||
gpioInit();
|
||||
// Set GPIO1.8 to input
|
||||
gpioSetDir(1, 8, gpioDirection_Input);
|
||||
// Disable the internal pullup/down resistor on P1.8
|
||||
gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_Inactive);
|
||||
// Setup an interrupt on GPIO1.8
|
||||
gpioSetInterrupt(1, // Port
|
||||
8, // Pin
|
||||
gpioInterruptSense_Edge, // Edge/Level Sensitive
|
||||
gpioInterruptEdge_Single, // Single/Double Edge
|
||||
gpioInterruptEvent_ActiveHigh); // Rising/Falling
|
||||
// Enable the interrupt
|
||||
gpioIntEnable(1, 8);
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioSetInterrupt (uint32_t portNum, uint32_t bitPos, gpioInterruptSense_t sense, gpioInterruptEdge_t edge, gpioInterruptEvent_t event)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
// Get the appropriate register (handled this way to optimise code size)
|
||||
REG32 *gpiois = &GPIO_GPIO0IS;
|
||||
REG32 *gpioibe = &GPIO_GPIO0IBE;
|
||||
REG32 *gpioiev = &GPIO_GPIO0IEV;
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
gpiois = &GPIO_GPIO0IS;
|
||||
gpioibe = &GPIO_GPIO0IBE;
|
||||
gpioiev = &GPIO_GPIO0IEV;
|
||||
break;
|
||||
case 1:
|
||||
gpiois = &GPIO_GPIO1IS;
|
||||
gpioibe = &GPIO_GPIO1IBE;
|
||||
gpioiev = &GPIO_GPIO1IEV;
|
||||
break;
|
||||
case 2:
|
||||
gpiois = &GPIO_GPIO2IS;
|
||||
gpioibe = &GPIO_GPIO2IBE;
|
||||
gpioiev = &GPIO_GPIO2IEV;
|
||||
break;
|
||||
case 3:
|
||||
gpiois = &GPIO_GPIO3IS;
|
||||
gpioibe = &GPIO_GPIO3IBE;
|
||||
gpioiev = &GPIO_GPIO3IEV;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gpioInterruptSense_Edge)
|
||||
{
|
||||
*gpiois &= ~(0x1<<bitPos);
|
||||
/* single or double only applies when sense is 0(edge trigger). */
|
||||
gpioInterruptEdge_Single ? (*gpioibe &= ~(0x1<<bitPos)) : (*gpioibe |= (0x1<<bitPos));
|
||||
}
|
||||
else
|
||||
{
|
||||
*gpiois |= (0x1<<bitPos);
|
||||
}
|
||||
|
||||
gpioInterruptEvent_ActiveHigh ? (*gpioiev &= ~(0x1<<bitPos)) : (*gpioiev |= (0x1<<bitPos));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Enables the interrupt mask for a specific port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioIntEnable (uint32_t portNum, uint32_t bitPos)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
GPIO_GPIO0IE |= (0x1<<bitPos);
|
||||
break;
|
||||
case 1:
|
||||
GPIO_GPIO1IE |= (0x1<<bitPos);
|
||||
break;
|
||||
case 2:
|
||||
GPIO_GPIO2IE |= (0x1<<bitPos);
|
||||
break;
|
||||
case 3:
|
||||
GPIO_GPIO3IE |= (0x1<<bitPos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Disables the interrupt mask for a specific port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioIntDisable (uint32_t portNum, uint32_t bitPos)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
GPIO_GPIO0IE &= ~(0x1<<bitPos);
|
||||
break;
|
||||
case 1:
|
||||
GPIO_GPIO1IE &= ~(0x1<<bitPos);
|
||||
break;
|
||||
case 2:
|
||||
GPIO_GPIO2IE &= ~(0x1<<bitPos);
|
||||
break;
|
||||
case 3:
|
||||
GPIO_GPIO3IE &= ~(0x1<<bitPos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the interrupt status for a specific port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
|
||||
@return The interrupt status for the specified port pin (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t gpioIntStatus (uint32_t portNum, uint32_t bitPos)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
uint32_t regVal = 0;
|
||||
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
if (GPIO_GPIO0MIS & (0x1<<bitPos))
|
||||
{
|
||||
regVal = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (GPIO_GPIO1MIS & (0x1<<bitPos))
|
||||
{
|
||||
regVal = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (GPIO_GPIO2MIS & (0x1<<bitPos))
|
||||
{
|
||||
regVal = 1;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (GPIO_GPIO3MIS & (0x1<<bitPos))
|
||||
{
|
||||
regVal = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ( regVal );
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Clears the interrupt for a port pin
|
||||
|
||||
@param[in] portNum
|
||||
The port number (0..3)
|
||||
@param[in] bitPos
|
||||
The bit position (0..31)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioIntClear (uint32_t portNum, uint32_t bitPos)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
switch (portNum)
|
||||
{
|
||||
case 0:
|
||||
GPIO_GPIO0IC |= (0x1<<bitPos);
|
||||
break;
|
||||
case 1:
|
||||
GPIO_GPIO1IC |= (0x1<<bitPos);
|
||||
break;
|
||||
case 2:
|
||||
GPIO_GPIO2IC |= (0x1<<bitPos);
|
||||
break;
|
||||
case 3:
|
||||
GPIO_GPIO3IC |= (0x1<<bitPos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures the internal pullup/down resistor for GPIO pins
|
||||
(only relevant for pins configured as inputs)
|
||||
|
||||
@param[in] ioconReg
|
||||
A pointer to the IOCON registry value corresponding to
|
||||
the pin you wish to change (for example: &IOCON_PIO2_0
|
||||
for GPIO pin 2.0).
|
||||
@param[in] mode
|
||||
The 'mode' that the pin should be set to, which must be
|
||||
correspond to a value defined in gpioPullupMode_t
|
||||
|
||||
@warning By default, all GPIO pins have the internal pull-up
|
||||
resistor enabled. This may cause unusual behaviour if
|
||||
care isn't taken to set the internal resistor to an
|
||||
appropriate state.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Initialise gpio
|
||||
gpioInit();
|
||||
// Set GPIO1.8 to input
|
||||
gpioSetDir(1, 8, gpioDirection_Input);
|
||||
// Disable the internal pullup/down resistor on P1.8
|
||||
gpioSetPullup(&IOCON_PIO1_8, gpioPullupMode_Inactive);
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void gpioSetPullup (volatile uint32_t *ioconReg, gpioPullupMode_t mode)
|
||||
{
|
||||
if (!_gpioInitialised) gpioInit();
|
||||
|
||||
// ToDo: Disable interrupts while we are doing this?
|
||||
|
||||
*ioconReg &= ~(IOCON_COMMON_MODE_MASK);
|
||||
*ioconReg |= mode;
|
||||
|
||||
// ToDo: Re-enable interrupts?
|
||||
};
|
|
@ -0,0 +1,112 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file gpio.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _GPIO_H_
|
||||
#define _GPIO_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Indicates whether the interrupt should be configured as edge or
|
||||
level sensitive.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum gpioInterruptSense_e
|
||||
{
|
||||
gpioInterruptSense_Edge = 0,
|
||||
gpioInterruptSense_Level
|
||||
}
|
||||
gpioInterruptSense_t;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Indicates whether one edge or both edges trigger an interrupt.
|
||||
Setting this to Double will cause both edges to trigger an interrupt.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum gpioInterruptEdge_e
|
||||
{
|
||||
gpioInterruptEdge_Single = 0,
|
||||
gpioInterruptEdge_Double
|
||||
}
|
||||
gpioInterruptEdge_t;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Indicates whether the interrupt should be triggered in the rising
|
||||
or falling edge. ActiveHigh means that a HIGH level on the pin will
|
||||
trigger an interrupt, ActiveLow means that a LOW level on the pin
|
||||
will trigger an interrupt.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum gpioInterruptEvent_e
|
||||
{
|
||||
gpioInterruptEvent_ActiveHigh = 0,
|
||||
gpioInterruptEvent_ActiveLow
|
||||
}
|
||||
gpioInterruptEvent_t;
|
||||
|
||||
typedef enum gpioDirection_e
|
||||
{
|
||||
gpioDirection_Input = 0,
|
||||
gpioDirection_Output
|
||||
}
|
||||
gpioDirection_t;
|
||||
|
||||
typedef enum gpioPullupMode_e
|
||||
{
|
||||
gpioPullupMode_Inactive = IOCON_COMMON_MODE_INACTIVE,
|
||||
gpioPullupMode_PullDown = IOCON_COMMON_MODE_PULLDOWN,
|
||||
gpioPullupMode_PullUp = IOCON_COMMON_MODE_PULLUP,
|
||||
gpioPullupMode_Repeater = IOCON_COMMON_MODE_REPEATER
|
||||
}
|
||||
gpioPullupMode_t;
|
||||
|
||||
void gpioInit (void);
|
||||
void gpioSetDir (uint32_t portNum, uint32_t bitPos, gpioDirection_t dir);
|
||||
uint32_t gpioGetValue (uint32_t portNum, uint32_t bitPos);
|
||||
void gpioSetValue (uint32_t portNum, uint32_t bitPos, uint32_t bitVal);
|
||||
void gpioSetInterrupt (uint32_t portNum, uint32_t bitPos, gpioInterruptSense_t sense, gpioInterruptEdge_t edge, gpioInterruptEvent_t event);
|
||||
void gpioIntEnable (uint32_t portNum, uint32_t bitPos);
|
||||
void gpioIntDisable (uint32_t portNum, uint32_t bitPos);
|
||||
uint32_t gpioIntStatus (uint32_t portNum, uint32_t bitPos);
|
||||
void gpioIntClear (uint32_t portNum, uint32_t bitPos);
|
||||
void gpioSetPullup (volatile uint32_t *ioconRegister, gpioPullupMode_t mode);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,353 @@
|
|||
/*****************************************************************************
|
||||
* i2c.c: I2C C file for NXP LPC11xx/13xx Family Microprocessors
|
||||
*
|
||||
* Copyright(C) 2008, NXP Semiconductor
|
||||
* Parts of this code are (C) 2010, MyVoice CAD/CAM Services
|
||||
* All rights reserved.
|
||||
*
|
||||
* History
|
||||
* 2009.12.07 ver 1.00 Preliminary version, first Release
|
||||
* 2010.07.19 ver 1.10 Rob Jansen - MyVoice CAD/CAM Services:
|
||||
* Major cleaning and a rewrite of some functions
|
||||
* - adding ACK/NACK handling to the state machine
|
||||
* - adding a return result to the I2CEngine()
|
||||
*
|
||||
*****************************************************************************/
|
||||
#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 uint32_t I2CReadLength;
|
||||
volatile uint32_t I2CWriteLength;
|
||||
|
||||
volatile uint32_t RdIndex = 0;
|
||||
volatile uint32_t WrIndex = 0;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Function name: I2C_IRQHandler
|
||||
**
|
||||
** Descriptions: I2C interrupt handler, deal with master mode only.
|
||||
**
|
||||
** parameters: None
|
||||
** Returned value: None
|
||||
**
|
||||
*****************************************************************************/
|
||||
void I2C_IRQHandler(void)
|
||||
{
|
||||
uint8_t StatValue;
|
||||
|
||||
/* this handler deals with master read and master write only */
|
||||
StatValue = I2C_I2CSTAT;
|
||||
switch ( StatValue )
|
||||
{
|
||||
case 0x08:
|
||||
/*
|
||||
* A START condition has been transmitted.
|
||||
* We now send the slave address and initialize
|
||||
* the write buffer
|
||||
* (we always start with a write after START+SLA)
|
||||
*/
|
||||
WrIndex = 0;
|
||||
I2C_I2CDAT = I2CMasterBuffer[WrIndex++];
|
||||
I2C_I2CCONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
I2CMasterState = I2CSTATE_PENDING;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
/*
|
||||
* A repeated START condition has been transmitted.
|
||||
* Now a second, read, transaction follows so we
|
||||
* initialize the read buffer.
|
||||
*/
|
||||
RdIndex = 0;
|
||||
/* Send SLA with R bit set, */
|
||||
I2C_I2CDAT = I2CMasterBuffer[WrIndex++];
|
||||
I2C_I2CCONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
/*
|
||||
* SLA+W has been transmitted; ACK has been received.
|
||||
* We now start writing bytes.
|
||||
*/
|
||||
I2C_I2CDAT = I2CMasterBuffer[WrIndex++];
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
/*
|
||||
* SLA+W has been transmitted; NOT ACK has been received.
|
||||
* Send a stop condition to terminate the transaction
|
||||
* and signal I2CEngine the transaction is aborted.
|
||||
*/
|
||||
I2C_I2CCONSET = I2CONSET_STO;
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
I2CMasterState = I2CSTATE_SLA_NACK;
|
||||
break;
|
||||
|
||||
case 0x28:
|
||||
/*
|
||||
* Data in I2DAT has been transmitted; ACK has been received.
|
||||
* Continue sending more bytes as long as there are bytes to send
|
||||
* and after this check if a read transaction should follow.
|
||||
*/
|
||||
if ( WrIndex < I2CWriteLength )
|
||||
{
|
||||
/* Keep writing as long as bytes avail */
|
||||
I2C_I2CDAT = I2CMasterBuffer[WrIndex++];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( I2CReadLength != 0 )
|
||||
{
|
||||
/* Send a Repeated START to initialize a read transaction */
|
||||
/* (handled in state 0x10) */
|
||||
I2C_I2CCONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
}
|
||||
else
|
||||
{
|
||||
I2CMasterState = I2CSTATE_ACK;
|
||||
I2C_I2CCONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
}
|
||||
}
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x30:
|
||||
/*
|
||||
* Data byte in I2DAT has been transmitted; NOT ACK has been received
|
||||
* Send a STOP condition to terminate the transaction and inform the
|
||||
* I2CEngine that the transaction failed.
|
||||
*/
|
||||
I2C_I2CCONSET = I2CONSET_STO;
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
I2CMasterState = I2CSTATE_NACK;
|
||||
break;
|
||||
|
||||
case 0x38:
|
||||
/*
|
||||
* Arbitration loss in SLA+R/W or Data bytes.
|
||||
* This is a fatal condition, the transaction did not complete due
|
||||
* to external reasons (e.g. hardware system failure).
|
||||
* Inform the I2CEngine of this and cancel the transaction
|
||||
* (this is automatically done by the I2C hardware)
|
||||
*/
|
||||
I2CMasterState = I2CSTATE_ARB_LOSS;
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
/*
|
||||
* SLA+R has been transmitted; ACK has been received.
|
||||
* Initialize a read.
|
||||
* Since a NOT ACK is sent after reading the last byte,
|
||||
* we need to prepare a NOT ACK in case we only read 1 byte.
|
||||
*/
|
||||
if ( I2CReadLength == 1 )
|
||||
{
|
||||
/* last (and only) byte: send a NACK after data is received */
|
||||
I2C_I2CCONCLR = I2CONCLR_AAC;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* more bytes to follow: send an ACK after data is received */
|
||||
I2C_I2CCONSET = I2CONSET_AA;
|
||||
}
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
/*
|
||||
* SLA+R has been transmitted; NOT ACK has been received.
|
||||
* Send a stop condition to terminate the transaction
|
||||
* and signal I2CEngine the transaction is aborted.
|
||||
*/
|
||||
I2C_I2CCONSET = I2CONSET_STO;
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
I2CMasterState = I2CSTATE_SLA_NACK;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
/*
|
||||
* Data byte has been received; ACK has been returned.
|
||||
* Read the byte and check for more bytes to read.
|
||||
* Send a NOT ACK after the last byte is received
|
||||
*/
|
||||
I2CSlaveBuffer[RdIndex++] = I2C_I2CDAT;
|
||||
if ( RdIndex < (I2CReadLength-1) )
|
||||
{
|
||||
/* lmore bytes to follow: send an ACK after data is received */
|
||||
I2C_I2CCONSET = I2CONSET_AA;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* last byte: send a NACK after data is received */
|
||||
I2C_I2CCONCLR = I2CONCLR_AAC;
|
||||
}
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
/*
|
||||
* Data byte has been received; NOT ACK has been returned.
|
||||
* This is the last byte to read.
|
||||
* Generate a STOP condition and flag the I2CEngine that the
|
||||
* transaction is finished.
|
||||
*/
|
||||
I2CSlaveBuffer[RdIndex++] = I2C_I2CDAT;
|
||||
I2CMasterState = I2CSTATE_ACK;
|
||||
I2C_I2CCONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC; /* Clear SI flag */
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
I2C_I2CCONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function name: I2CStart
|
||||
**
|
||||
** Descriptions: Create I2C start condition, a timeout
|
||||
** value is set if the I2C never gets started,
|
||||
** and timed out. It's a fatal error.
|
||||
**
|
||||
** parameters: None
|
||||
** Returned value: true or false, return false if timed out
|
||||
**
|
||||
*****************************************************************************/
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function name: I2CStop
|
||||
**
|
||||
** Descriptions: Set the I2C stop condition
|
||||
**
|
||||
** parameters: None
|
||||
** Returned value: true or never return
|
||||
**
|
||||
*****************************************************************************/
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function name: I2CInit
|
||||
**
|
||||
** Descriptions: Initialize I2C controller
|
||||
**
|
||||
** parameters: I2c mode is either MASTER or SLAVE
|
||||
** Returned value: true or false, return false if the I2C
|
||||
** interrupt handler was not installed correctly
|
||||
**
|
||||
*****************************************************************************/
|
||||
uint32_t i2cInit( uint32_t I2cMode )
|
||||
{
|
||||
SCB_PRESETCTRL |= (0x1<<1);
|
||||
|
||||
// Enable I2C clock
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_I2C);
|
||||
|
||||
// Configure pin 0.4 for SCL
|
||||
IOCON_PIO0_4 &= ~(IOCON_PIO0_4_FUNC_MASK | IOCON_PIO0_4_I2CMODE_MASK);
|
||||
IOCON_PIO0_4 |= (IOCON_PIO0_4_FUNC_I2CSCL);
|
||||
|
||||
// Configure pin 0.5 for SDA
|
||||
IOCON_PIO0_5 &= ~(IOCON_PIO0_5_FUNC_MASK | IOCON_PIO0_5_I2CMODE_MASK);
|
||||
IOCON_PIO0_5 |= IOCON_PIO0_5_FUNC_I2CSDA;
|
||||
|
||||
// Clear flags
|
||||
I2C_I2CCONCLR = I2C_I2CCONCLR_AAC |
|
||||
I2C_I2CCONCLR_SIC |
|
||||
I2C_I2CCONCLR_STAC |
|
||||
I2C_I2CCONCLR_I2ENC;
|
||||
|
||||
// See p.128 for appropriate values for SCLL and SCLH
|
||||
#if I2C_FAST_MODE_PLUS
|
||||
IOCON_PIO0_4 |= (IOCON_PIO0_4_I2CMODE_FASTPLUSI2C);
|
||||
IOCON_PIO0_5 |= (IOCON_PIO0_5_I2CMODE_FASTPLUSI2C);
|
||||
I2C_I2CSCLL = I2C_SCLL_HS_SCLL;
|
||||
I2C_I2CSCLH = I2C_SCLH_HS_SCLH;
|
||||
#else
|
||||
I2C_I2CSCLL = I2SCLL_SCLL;
|
||||
I2C_I2CSCLH = I2SCLH_SCLH;
|
||||
#endif
|
||||
|
||||
if ( I2cMode == I2CSLAVE )
|
||||
{
|
||||
I2C_I2CADR0 = SLAVE_ADDR;
|
||||
}
|
||||
|
||||
/* Enable the I2C Interrupt */
|
||||
NVIC_EnableIRQ(I2C_IRQn);
|
||||
I2C_I2CCONSET = I2C_I2CCONSET_I2EN;
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Function name: I2CEngine
|
||||
**
|
||||
** Descriptions: The routine to complete a I2C transaction
|
||||
** from start to stop. All the intermitten
|
||||
** steps are handled in the interrupt handler.
|
||||
** Before this routine is called, the read
|
||||
** length, write length and I2C master buffer
|
||||
** need to be filled.
|
||||
**
|
||||
** parameters: None
|
||||
** Returned value: Any of the I2CSTATE_... values. See i2c.h
|
||||
**
|
||||
*****************************************************************************/
|
||||
uint32_t i2cEngine( void )
|
||||
{
|
||||
I2CMasterState = I2CSTATE_IDLE;
|
||||
RdIndex = 0;
|
||||
WrIndex = 0;
|
||||
if ( I2CStart() != TRUE )
|
||||
{
|
||||
I2CStop();
|
||||
return ( FALSE );
|
||||
}
|
||||
|
||||
/* wait until the state is a terminal state */
|
||||
while (I2CMasterState < 0x100);
|
||||
|
||||
return ( I2CMasterState );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** End Of File
|
||||
******************************************************************************/
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*****************************************************************************
|
||||
* i2c.h: Header file for NXP LPC11xx Family Microprocessors
|
||||
*
|
||||
* Copyright(C) 2006, NXP Semiconductor
|
||||
* Parts of this code are (C) 2010, MyVoice CAD/CAM Services
|
||||
* All rights reserved.
|
||||
*
|
||||
* History
|
||||
* 2006.07.19 ver 1.00 Preliminary version, first Release
|
||||
* 2010.07.19 ver 1.10 Rob Jansen - MyVoice CAD/CAM Services
|
||||
* Updated to reflect new code
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __I2C_H
|
||||
#define __I2C_H
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
/*
|
||||
* These are states returned by the I2CEngine:
|
||||
*
|
||||
* IDLE - is never returned but only used internally
|
||||
* PENDING - is never returned but only used internally in the I2C functions
|
||||
* ACK - The transaction finished and the slave returned ACK (on all bytes)
|
||||
* NACK - The transaction is aborted since the slave returned a NACK
|
||||
* SLA_NACK - The transaction is aborted since the slave returned a NACK on the SLA
|
||||
* this can be intentional (e.g. an 24LC08 EEPROM states it is busy)
|
||||
* or the slave is not available/accessible at all.
|
||||
* ARB_LOSS - Arbitration loss during any part of the transaction.
|
||||
* This could only happen in a multi master system or could also
|
||||
* identify a hardware problem in the system.
|
||||
*/
|
||||
#define I2CSTATE_IDLE 0x000
|
||||
#define I2CSTATE_PENDING 0x001
|
||||
#define I2CSTATE_ACK 0x101
|
||||
#define I2CSTATE_NACK 0x102
|
||||
#define I2CSTATE_SLA_NACK 0x103
|
||||
#define I2CSTATE_ARB_LOSS 0x104
|
||||
|
||||
#define FAST_MODE_PLUS 0
|
||||
|
||||
#define I2C_BUFSIZE 6
|
||||
#define MAX_TIMEOUT 0x00FFFFFF
|
||||
|
||||
#define I2CMASTER 0x01
|
||||
#define I2CSLAVE 0x02
|
||||
|
||||
#define SLAVE_ADDR 0xA0
|
||||
#define READ_WRITE 0x01
|
||||
|
||||
#define RD_BIT 0x01
|
||||
|
||||
#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */
|
||||
#define I2CONSET_AA 0x00000004
|
||||
#define I2CONSET_SI 0x00000008
|
||||
#define I2CONSET_STO 0x00000010
|
||||
#define I2CONSET_STA 0x00000020
|
||||
|
||||
#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
|
||||
#define I2CONCLR_SIC 0x00000008
|
||||
#define I2CONCLR_STAC 0x00000020
|
||||
#define I2CONCLR_I2ENC 0x00000040
|
||||
|
||||
#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
|
||||
#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
|
||||
#define I2SCLH_SCLH 120 /* I2C SCL Duty Cycle High Reg */
|
||||
#define I2SCLL_SCLL 120 /* I2C SCL Duty Cycle Low Reg */
|
||||
#define I2SCLH_HS_SCLH 0x00000020 /* Fast Plus I2C SCL Duty Cycle High Reg */
|
||||
#define I2SCLL_HS_SCLL 0x00000020 /* Fast Plus I2C SCL Duty Cycle Low Reg */
|
||||
|
||||
|
||||
extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
|
||||
extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
|
||||
extern volatile uint32_t I2CReadLength, I2CWriteLength;
|
||||
|
||||
extern void I2C_IRQHandler( void );
|
||||
extern uint32_t i2cInit( uint32_t I2cMode );
|
||||
extern uint32_t i2cEngine( void );
|
||||
|
||||
#endif /* end __I2C_H */
|
||||
/****************************************************************************
|
||||
** End Of File
|
||||
*****************************************************************************/
|
|
@ -0,0 +1,57 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file iap.c
|
||||
Source: http://knowledgebase.nxp.com/showthread.php?t=1594
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#include "iap.h"
|
||||
|
||||
IAP_return_t iap_return;
|
||||
|
||||
#define IAP_ADDRESS 0x1FFF1FF1
|
||||
uint32_t param_table[5];
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Sends the IAP command and stores the result
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void iap_entry(uint32_t param_tab[], uint32_t result_tab[])
|
||||
{
|
||||
void (*iap)(uint32_t[], uint32_t[]);
|
||||
iap = (void (*)(uint32_t[], uint32_t[]))IAP_ADDRESS;
|
||||
iap(param_tab,result_tab);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Returns the CPU's unique 128-bit serial number (4 words long)
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/iap/iap.h"
|
||||
|
||||
IAP_return_t iap_return;
|
||||
iap_return = iapReadSerialNumber();
|
||||
|
||||
if (iap_return.ReturnCode == 0)
|
||||
{
|
||||
printf("Serial Number: %08X %08X %08X %08X %s",
|
||||
iap_return.Result[0],
|
||||
iap_return.Result[1],
|
||||
iap_return.Result[2],
|
||||
iap_return.Result[3],
|
||||
CFG_PRINTF_NEWLINE);
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
IAP_return_t iapReadSerialNumber(void)
|
||||
{
|
||||
// ToDo: Why does IAP sometime cause the application to halt when read???
|
||||
param_table[0] = IAP_CMD_READUID;
|
||||
iap_entry(param_table,(uint32_t*)(&iap_return));
|
||||
return iap_return;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file iap.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _IAP_H_
|
||||
#define _IAP_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#define IAP_CMD_PREPARESECTORFORWRITE (50)
|
||||
#define IAP_CMD_COPYRAMTOFLASH (51)
|
||||
#define CAP_CMD_ERASESECTORS (52)
|
||||
#define IAP_CMD_BLANKCHECKSECTOR (53)
|
||||
#define IAP_CMD_READPARTID (54)
|
||||
#define IAP_CMD_READBOOTCODEVERSION (55)
|
||||
#define IAP_CMD_COMPARE (56)
|
||||
#define IAP_CMD_REINVOKEISP (57)
|
||||
#define IAP_CMD_READUID (58)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int ReturnCode;
|
||||
unsigned int Result[4];
|
||||
} IAP_return_t;
|
||||
|
||||
IAP_return_t iapReadSerialNumber(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* This file is part of the libpayload project.
|
||||
*
|
||||
* Copyright (C) 2008 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
int isalpha(int c)
|
||||
{
|
||||
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
|
||||
}
|
||||
|
||||
int isascii(int c)
|
||||
{
|
||||
return (c >= 0 && c <= 127);
|
||||
}
|
||||
|
||||
int isblank(int c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
int iscntrl(int c)
|
||||
{
|
||||
return (c <= 31 || c == 127);
|
||||
}
|
||||
|
||||
int isdigit(int c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
int isalnum(int c)
|
||||
{
|
||||
return isalpha(c) || isdigit(c);
|
||||
}
|
||||
|
||||
int isgraph(int c)
|
||||
{
|
||||
return (c >= 33 && c <= 126);
|
||||
}
|
||||
|
||||
int islower(int c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z');
|
||||
}
|
||||
|
||||
int isprint(int c)
|
||||
{
|
||||
return (c >= 32 && c <= 126);
|
||||
}
|
||||
|
||||
|
||||
int isspace(int c)
|
||||
{
|
||||
return (c == ' ' || (c >= '\t' || c <= '\r'));
|
||||
}
|
||||
|
||||
int isupper(int c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
|
||||
int tolower(int c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') ? (c + 32) : c;
|
||||
}
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z') ? (c - 32) : c;
|
||||
}
|
||||
|
||||
int isxdigit(int c)
|
||||
{
|
||||
return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'z');
|
||||
}
|
||||
|
||||
int ispunct(int c)
|
||||
{
|
||||
return isprint(c) && !isspace(c) && !isalnum(c);
|
||||
}
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Based on original stdio.c released by Atmel
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by Roel Verdult, Copyright (c) 2010
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Headers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Local Definitions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Maximum string size allowed (in bytes).
|
||||
#define MAX_STRING_SIZE 255
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Global Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Required for proper compilation.
|
||||
//struct _reent r = {0, (FILE*) 0, (FILE*) 1, (FILE*) 0};
|
||||
//struct _reent *_impure_ptr = &r;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Local Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Writes a character inside the given string. Returns 1.
|
||||
// \param pStr Storage string.
|
||||
// \param c Character to write.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int append_char(char *pStr, char c)
|
||||
{
|
||||
*pStr = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Writes a string inside the given string.
|
||||
// Returns the size of the written
|
||||
// string.
|
||||
// \param pStr Storage string.
|
||||
// \param pSource Source string.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int PutString(char *pStr, char fill, signed int width, const char *pSource)
|
||||
{
|
||||
signed int num = 0;
|
||||
|
||||
while (*pSource != 0) {
|
||||
|
||||
*pStr++ = *pSource++;
|
||||
num++;
|
||||
}
|
||||
|
||||
width -= num;
|
||||
while (width > 0) {
|
||||
|
||||
*pStr++ = fill;
|
||||
num++;
|
||||
width--;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Writes an unsigned int inside the given string, using the provided fill &
|
||||
// width parameters.
|
||||
// Returns the size in characters of the written integer.
|
||||
// \param pStr Storage string.
|
||||
// \param fill Fill character.
|
||||
// \param width Minimum integer width.
|
||||
// \param value Integer value.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int PutUnsignedInt(
|
||||
char *pStr,
|
||||
char fill,
|
||||
signed int width,
|
||||
unsigned int value)
|
||||
{
|
||||
signed int num = 0;
|
||||
|
||||
// Take current digit into account when calculating width
|
||||
width--;
|
||||
|
||||
// Recursively write upper digits
|
||||
if ((value / 10) > 0) {
|
||||
|
||||
num = PutUnsignedInt(pStr, fill, width, value / 10);
|
||||
pStr += num;
|
||||
}
|
||||
// Write filler characters
|
||||
else {
|
||||
|
||||
while (width > 0) {
|
||||
|
||||
append_char(pStr, fill);
|
||||
pStr++;
|
||||
num++;
|
||||
width--;
|
||||
}
|
||||
}
|
||||
|
||||
// Write lower digit
|
||||
num += append_char(pStr, (value % 10) + '0');
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Writes a signed int inside the given string, using the provided fill & width
|
||||
// parameters.
|
||||
// Returns the size of the written integer.
|
||||
// \param pStr Storage string.
|
||||
// \param fill Fill character.
|
||||
// \param width Minimum integer width.
|
||||
// \param value Signed integer value.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int PutSignedInt(
|
||||
char *pStr,
|
||||
char fill,
|
||||
signed int width,
|
||||
signed int value)
|
||||
{
|
||||
signed int num = 0;
|
||||
unsigned int absolute;
|
||||
|
||||
// Compute absolute value
|
||||
if (value < 0) {
|
||||
|
||||
absolute = -value;
|
||||
}
|
||||
else {
|
||||
|
||||
absolute = value;
|
||||
}
|
||||
|
||||
// Take current digit into account when calculating width
|
||||
width--;
|
||||
|
||||
// Recursively write upper digits
|
||||
if ((absolute / 10) > 0) {
|
||||
|
||||
if (value < 0) {
|
||||
|
||||
num = PutSignedInt(pStr, fill, width, -(absolute / 10));
|
||||
}
|
||||
else {
|
||||
|
||||
num = PutSignedInt(pStr, fill, width, absolute / 10);
|
||||
}
|
||||
pStr += num;
|
||||
}
|
||||
else {
|
||||
|
||||
// Reserve space for sign
|
||||
if (value < 0) {
|
||||
|
||||
width--;
|
||||
}
|
||||
|
||||
// Write filler characters
|
||||
while (width > 0) {
|
||||
|
||||
append_char(pStr, fill);
|
||||
pStr++;
|
||||
num++;
|
||||
width--;
|
||||
}
|
||||
|
||||
// Write sign
|
||||
if (value < 0) {
|
||||
|
||||
num += append_char(pStr, '-');
|
||||
pStr++;
|
||||
}
|
||||
}
|
||||
|
||||
// Write lower digit
|
||||
num += append_char(pStr, (absolute % 10) + '0');
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Writes an hexadecimal value into a string, using the given fill, width &
|
||||
// capital parameters.
|
||||
// Returns the number of char written.
|
||||
// \param pStr Storage string.
|
||||
// \param fill Fill character.
|
||||
// \param width Minimum integer width.
|
||||
// \param maj Indicates if the letters must be printed in lower- or upper-case.
|
||||
// \param value Hexadecimal value.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int PutHexa(
|
||||
char *pStr,
|
||||
char fill,
|
||||
signed int width,
|
||||
unsigned char maj,
|
||||
unsigned int value)
|
||||
{
|
||||
signed int num = 0;
|
||||
|
||||
// Decrement width
|
||||
width--;
|
||||
|
||||
// Recursively output upper digits
|
||||
if ((value >> 4) > 0) {
|
||||
|
||||
num += PutHexa(pStr, fill, width, maj, value >> 4);
|
||||
pStr += num;
|
||||
}
|
||||
// Write filler chars
|
||||
else {
|
||||
|
||||
while (width > 0) {
|
||||
|
||||
append_char(pStr, fill);
|
||||
pStr++;
|
||||
num++;
|
||||
width--;
|
||||
}
|
||||
}
|
||||
|
||||
// Write current digit
|
||||
if ((value & 0xF) < 10) {
|
||||
|
||||
append_char(pStr, (value & 0xF) + '0');
|
||||
}
|
||||
else if (maj) {
|
||||
|
||||
append_char(pStr, (value & 0xF) - 10 + 'A');
|
||||
}
|
||||
else {
|
||||
|
||||
append_char(pStr, (value & 0xF) - 10 + 'a');
|
||||
}
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Stores the result of a formatted string into another string. Format
|
||||
/// arguments are given in a va_list instance.
|
||||
/// Return the number of characters written.
|
||||
/// \param pStr Destination string.
|
||||
/// \param length Length of Destination string.
|
||||
/// \param pFormat Format string.
|
||||
/// \param ap Argument list.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
|
||||
{
|
||||
char fill;
|
||||
unsigned char width;
|
||||
signed int num = 0;
|
||||
signed int size = 0;
|
||||
|
||||
// Clear the string
|
||||
if (pStr) {
|
||||
|
||||
*pStr = 0;
|
||||
}
|
||||
|
||||
// Phase string
|
||||
while (*pFormat != 0 && size < length) {
|
||||
|
||||
// Normal character
|
||||
if (*pFormat != '%') {
|
||||
|
||||
*pStr++ = *pFormat++;
|
||||
size++;
|
||||
}
|
||||
// Escaped '%'
|
||||
else if (*(pFormat+1) == '%') {
|
||||
|
||||
*pStr++ = '%';
|
||||
pFormat += 2;
|
||||
size++;
|
||||
}
|
||||
// Token delimiter
|
||||
else {
|
||||
|
||||
fill = ' ';
|
||||
width = 0;
|
||||
pFormat++;
|
||||
|
||||
// Parse filler
|
||||
if (*pFormat == '0') {
|
||||
|
||||
fill = '0';
|
||||
pFormat++;
|
||||
}
|
||||
|
||||
// Ignore justifier
|
||||
if (*pFormat == '-') {
|
||||
pFormat++;
|
||||
}
|
||||
|
||||
// Parse width
|
||||
while ((*pFormat >= '0') && (*pFormat <= '9')) {
|
||||
|
||||
width = (width*10) + *pFormat-'0';
|
||||
pFormat++;
|
||||
}
|
||||
|
||||
// Check if there is enough space
|
||||
if (size + width > length) {
|
||||
|
||||
width = length - size;
|
||||
}
|
||||
|
||||
// Parse type
|
||||
switch (*pFormat) {
|
||||
case 'd':
|
||||
case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
|
||||
case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
|
||||
case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
|
||||
case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
|
||||
case 's': num = PutString(pStr, fill, width, va_arg(ap, char *)); break;
|
||||
case 'c': num = append_char(pStr, va_arg(ap, unsigned int)); break;
|
||||
default:
|
||||
return EOF;
|
||||
}
|
||||
|
||||
pFormat++;
|
||||
pStr += num;
|
||||
size += num;
|
||||
}
|
||||
}
|
||||
|
||||
// NULL-terminated (final \0 is not counted)
|
||||
if (size < length) {
|
||||
|
||||
*pStr = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
*(--pStr) = 0;
|
||||
size--;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Stores the result of a formatted string into another string. Format
|
||||
/// arguments are given in a va_list instance.
|
||||
/// Return the number of characters written.
|
||||
/// \param pString Destination string.
|
||||
/// \param length Length of Destination string.
|
||||
/// \param pFormat Format string.
|
||||
/// \param ... Other arguments
|
||||
//------------------------------------------------------------------------------
|
||||
signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
|
||||
{
|
||||
va_list ap;
|
||||
signed int rc;
|
||||
|
||||
va_start(ap, pFormat);
|
||||
rc = vsnprintf(pString, length, pFormat, ap);
|
||||
va_end(ap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Stores the result of a formatted string into another string. Format
|
||||
/// arguments are given in a va_list instance.
|
||||
/// Return the number of characters written.
|
||||
/// \param pString Destination string.
|
||||
/// \param pFormat Format string.
|
||||
/// \param ap Argument list.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int vsprintf(char *pString, const char *pFormat, va_list ap)
|
||||
{
|
||||
return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Outputs a formatted string on the DBGU stream. Format arguments are given
|
||||
/// in a va_list instance.
|
||||
/// \param pFormat Format string
|
||||
/// \param ap Argument list.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int vprintf(const char *pFormat, va_list ap)
|
||||
{
|
||||
char pStr[MAX_STRING_SIZE];
|
||||
char pError[] = "stdio.c: increase MAX_STRING_SIZE\r\n";
|
||||
|
||||
// Write formatted string in buffer
|
||||
if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
|
||||
|
||||
puts(pError);
|
||||
while (1); // Increase MAX_STRING_SIZE
|
||||
}
|
||||
|
||||
// Display string
|
||||
return puts(pStr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Outputs a formatted string on the DBGU stream, using a variable number of
|
||||
/// arguments.
|
||||
/// \param pFormat Format string.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int printf(const char *pFormat, ...)
|
||||
{
|
||||
va_list ap;
|
||||
signed int result;
|
||||
|
||||
// Forward call to vprintf
|
||||
va_start(ap, pFormat);
|
||||
result = vprintf(pFormat, ap);
|
||||
va_end(ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Writes a formatted string inside another string.
|
||||
/// \param pStr Storage string.
|
||||
/// \param pFormat Format string.
|
||||
//------------------------------------------------------------------------------
|
||||
signed int sprintf(char *pStr, const char *pFormat, ...)
|
||||
{
|
||||
va_list ap;
|
||||
signed int result;
|
||||
|
||||
// Forward call to vsprintf
|
||||
va_start(ap, pFormat);
|
||||
result = vsprintf(pStr, pFormat, ap);
|
||||
va_end(ap);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Based on original stdio.c released by Atmel
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by Roel Verdult, Copyright (c) 2010
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Headers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Copies data from a source buffer into a destination buffer. The two buffers
|
||||
/// must NOT overlap. Returns the destination buffer.
|
||||
/// \param pDestination Destination buffer.
|
||||
/// \param pSource Source buffer.
|
||||
/// \param num Number of bytes to copy.
|
||||
//------------------------------------------------------------------------------
|
||||
void * memcpy(void *pDestination, const void *pSource, size_t num)
|
||||
{
|
||||
unsigned char *pByteDestination;
|
||||
unsigned char *pByteSource;
|
||||
unsigned int *pAlignedSource = (unsigned int *) pSource;
|
||||
unsigned int *pAlignedDestination = (unsigned int *) pDestination;
|
||||
|
||||
// If num is more than 4 bytes, and both dest. and source are aligned,
|
||||
// then copy dwords
|
||||
if ((((unsigned int) pAlignedDestination & 0x3) == 0)
|
||||
&& (((unsigned int) pAlignedSource & 0x3) == 0)
|
||||
&& (num >= 4)) {
|
||||
|
||||
while (num >= 4) {
|
||||
|
||||
*pAlignedDestination++ = *pAlignedSource++;
|
||||
num -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy remaining bytes
|
||||
pByteDestination = (unsigned char *) pAlignedDestination;
|
||||
pByteSource = (unsigned char *) pAlignedSource;
|
||||
while (num--) {
|
||||
|
||||
*pByteDestination++ = *pByteSource++;
|
||||
}
|
||||
|
||||
return pDestination;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Fills a memory region with the given value. Returns a pointer to the
|
||||
/// memory region.
|
||||
/// \param pBuffer Pointer to the start of the memory region to fill
|
||||
/// \param value Value to fill the region with
|
||||
/// \param num Size to fill in bytes
|
||||
//------------------------------------------------------------------------------
|
||||
void * memset(void *pBuffer, int value, size_t num)
|
||||
{
|
||||
unsigned char *pByteDestination;
|
||||
unsigned int *pAlignedDestination = (unsigned int *) pBuffer;
|
||||
unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value;
|
||||
|
||||
// Set words if possible
|
||||
if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) {
|
||||
while (num >= 4) {
|
||||
*pAlignedDestination++ = alignedValue;
|
||||
num -= 4;
|
||||
}
|
||||
}
|
||||
// Set remaining bytes
|
||||
pByteDestination = (unsigned char *) pAlignedDestination;
|
||||
while (num--) {
|
||||
*pByteDestination++ = value;
|
||||
}
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
void* memmove(void *s1, const void *s2, size_t n)
|
||||
{
|
||||
char *s=(char*)s2, *d=(char*)s1;
|
||||
|
||||
if(d > s){
|
||||
s+=n-1;
|
||||
d+=n-1;
|
||||
while(n){
|
||||
*d--=*s--;
|
||||
n--;
|
||||
}
|
||||
}else if(d < s)
|
||||
while(n){
|
||||
*d++=*s++;
|
||||
n--;
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
|
||||
int memcmp(const void *av, const void *bv, size_t len)
|
||||
{
|
||||
const unsigned char *a = av;
|
||||
const unsigned char *b = bv;
|
||||
size_t i;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (a[i] != b[i])
|
||||
{
|
||||
return (int)(a[i] - b[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Search a character in the given string.
|
||||
/// Returns a pointer to the character location.
|
||||
/// \param pString Pointer to the start of the string to search.
|
||||
/// \param character The character to find.
|
||||
//-----------------------------------------------------------------------------
|
||||
char * strchr(const char *pString, int character)
|
||||
{
|
||||
char * p = (char *)pString;
|
||||
char c = character & 0xFF;
|
||||
|
||||
while(*p != c) {
|
||||
if (*p == 0) {
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Return the length of a given string
|
||||
/// \param pString Pointer to the start of the string.
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t strlen(const char *pString)
|
||||
{
|
||||
unsigned int length = 0;
|
||||
|
||||
while(*pString++ != 0) {
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Search a character backword from the end of given string.
|
||||
/// Returns a pointer to the character location.
|
||||
/// \param pString Pointer to the start of the string to search.
|
||||
/// \param character The character to find.
|
||||
//-----------------------------------------------------------------------------
|
||||
char * strrchr(const char *pString, int character)
|
||||
{
|
||||
char *p = 0;
|
||||
|
||||
while(*pString != 0) {
|
||||
if (*pString++ == character) {
|
||||
p = (char*)pString;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Copy from source string to destination string
|
||||
/// Return a pointer to the destination string
|
||||
/// \param pDestination Pointer to the destination string.
|
||||
/// \param pSource Pointer to the source string.
|
||||
//-----------------------------------------------------------------------------
|
||||
char * strcpy(char *pDestination, const char *pSource)
|
||||
{
|
||||
char *pSaveDest = pDestination;
|
||||
|
||||
for(; (*pDestination = *pSource) != 0; ++pSource, ++pDestination);
|
||||
return pSaveDest;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Compare the first specified bytes of 2 given strings
|
||||
/// Return 0 if equals
|
||||
/// Return >0 if 1st string > 2nd string
|
||||
/// Return <0 if 1st string < 2nd string
|
||||
/// \param pString1 Pointer to the start of the 1st string.
|
||||
/// \param pString2 Pointer to the start of the 2nd string.
|
||||
/// \param count Number of bytes that should be compared.
|
||||
//-----------------------------------------------------------------------------
|
||||
int strncmp(const char *pString1, const char *pString2, size_t count)
|
||||
{
|
||||
int r;
|
||||
|
||||
while(count) {
|
||||
r = *pString1 - *pString2;
|
||||
if (r == 0) {
|
||||
if (*pString1 == 0) {
|
||||
break;
|
||||
}
|
||||
pString1++;
|
||||
pString2++;
|
||||
count--;
|
||||
continue;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Copy the first number of bytes from source string to destination string
|
||||
/// Return the pointer to the destination string.
|
||||
/// \param pDestination Pointer to the start of destination string.
|
||||
/// \param pSource Pointer to the start of the source string.
|
||||
/// \param count Number of bytes that should be copied.
|
||||
//-----------------------------------------------------------------------------
|
||||
char * strncpy(char *pDestination, const char *pSource, size_t count)
|
||||
{
|
||||
char *pSaveDest = pDestination;
|
||||
|
||||
while (count) {
|
||||
*pDestination = *pSource;
|
||||
if (*pSource == 0) {
|
||||
break;
|
||||
}
|
||||
pDestination++;
|
||||
pSource++;
|
||||
count--;
|
||||
}
|
||||
return pSaveDest;
|
||||
}
|
||||
|
||||
// Following code is based on the BSD licensed code released by UoC
|
||||
// Copyright (c) 1988 Regents of the University of California
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 == *s2++)
|
||||
if (*s1++ == 0)
|
||||
return (0);
|
||||
return (*(unsigned char *)s1 - *(unsigned char *)--s2);
|
||||
}
|
||||
|
||||
char *strtok(char *s, const char *delim)
|
||||
{
|
||||
static char *last;
|
||||
return strtok_r(s, delim, &last);
|
||||
}
|
||||
|
||||
char *strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *spanp;
|
||||
int c, sc;
|
||||
char *tok;
|
||||
|
||||
|
||||
if (s == NULL && (s = *last) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
|
||||
if (c == sc)
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (c == 0) { /* no non-delimiter characters */
|
||||
*last = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (;;) {
|
||||
c = *s++;
|
||||
spanp = (char *)delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*last = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file pmu.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Controls the power management features of the LPC1343, allowing you
|
||||
to enter sleep/deep-sleep or deep power-down mode.
|
||||
|
||||
For examples of how to enter either mode, see the comments for the
|
||||
functions pmuSleep(), pmuDeepSleep() and pmuPowerDown().
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "core/gpio/gpio.h"
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/timer32/timer32.h"
|
||||
#include "pmu.h"
|
||||
|
||||
#ifdef CFG_CHIBI
|
||||
#include "drivers/chibi/chb_drvr.h"
|
||||
#endif
|
||||
#define PMU_WDTCLOCKSPEED_HZ 7812
|
||||
|
||||
void pmuSetupHW(void);
|
||||
void pmuRestoreHW(void);
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Wakeup interrupt handler
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WAKEUP_IRQHandler(void)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
// Reconfigure system clock/PLL
|
||||
cpuPllSetup(CPU_MULTIPLIER_6);
|
||||
|
||||
// Clear match bit on timer
|
||||
TMR_TMR32B0EMR = 0;
|
||||
|
||||
// Clear pending bits
|
||||
SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK;
|
||||
|
||||
// Clear SLEEPDEEP bit
|
||||
SCB_SCR &= ~SCB_SCR_SLEEPDEEP;
|
||||
|
||||
// Disable the deep sleep timer
|
||||
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED;
|
||||
|
||||
/* This handler takes care of all the port pins if they
|
||||
are configured as wakeup source. */
|
||||
regVal = SCB_STARTSRP0;
|
||||
if (regVal != 0)
|
||||
{
|
||||
SCB_STARTRSRP0CLR = regVal;
|
||||
}
|
||||
|
||||
// Reconfigure CT32B0
|
||||
timer32Init(0, TIMER32_DEFAULTINTERVAL);
|
||||
timer32Enable(0);
|
||||
|
||||
// Perform peripheral specific and custom wakeup tasks
|
||||
pmuRestoreHW();
|
||||
|
||||
/* See tracker for bug report. */
|
||||
__asm volatile ("NOP");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Setup the clock for the watchdog timer. The default is 7.8125kHz.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static void pmuWDTClockInit (void)
|
||||
{
|
||||
/* Enable WDT clock */
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC);
|
||||
|
||||
/* Configure watchdog clock */
|
||||
/* Freq. = 0.5MHz, div = 64: WDT_OSC = 7.8125kHz */
|
||||
SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ |
|
||||
SCB_WDTOSCCTRL_DIVSEL_DIV64;
|
||||
|
||||
// Switch main clock to WDT output
|
||||
SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_WDTOSC;
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once
|
||||
SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE;
|
||||
|
||||
// Wait until the clock is updated
|
||||
while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the power management unit
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuInit( void )
|
||||
{
|
||||
/* Enable all clocks, even those turned off at power up. */
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC_MASK |
|
||||
SCB_PDRUNCFG_SYSOSC_MASK |
|
||||
SCB_PDRUNCFG_ADC_MASK);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Puts select peripherals in sleep mode.
|
||||
|
||||
This function will put the device into sleep mode. Most gpio pins
|
||||
can be used to wake the device up, but the pins must first be
|
||||
configured for this in pmuInit.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Configure wakeup sources before going into sleep/deep-sleep.
|
||||
// By default, pin 0.1 is configured as wakeup source (falling edge)
|
||||
pmuInit();
|
||||
|
||||
// Enter sleep mode
|
||||
pmuSleep();
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuSleep()
|
||||
{
|
||||
SCB_PDAWAKECFG = SCB_PDRUNCFG;
|
||||
__asm volatile ("WFI");
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Turns off select peripherals and puts the device in deep-sleep
|
||||
mode.
|
||||
|
||||
The device can be configured to wakeup from deep-sleep mode after a
|
||||
specified delay by supplying a non-zero value to the wakeupSeconds
|
||||
parameter. This will configure CT32B0 to toggle pin 0.1 (CT32B0_MAT2)
|
||||
after x seconds, waking the device up. The timer will be configured
|
||||
to run off the WDT OSC while in deep-sleep mode, meaning that WDTOSC
|
||||
should not be powered off (using the sleepCtrl parameter) when a
|
||||
wakeup delay is specified.
|
||||
|
||||
The sleepCtrl parameter is used to indicate which peripherals should
|
||||
be put in sleep mode (see the SCB_PDSLEEPCFG register for details).
|
||||
|
||||
@param[in] sleepCtrl
|
||||
The bits to set in the SCB_PDSLEEPCFG register. This
|
||||
controls which peripherals will be put in sleep mode.
|
||||
@param[in] wakeupSeconds
|
||||
The number of seconds to wait until the device will
|
||||
wakeup. If you do not wish to wakeup after a specific
|
||||
delay, enter a value of 0.
|
||||
|
||||
@code
|
||||
uint32_t pmuRegVal;
|
||||
|
||||
// Initialise power management unit
|
||||
pmuInit();
|
||||
|
||||
// Put peripherals into sleep mode
|
||||
pmuRegVal = SCB_PDSLEEPCFG_IRCOUT_PD |
|
||||
SCB_PDSLEEPCFG_IRC_PD |
|
||||
SCB_PDSLEEPCFG_FLASH_PD |
|
||||
SCB_PDSLEEPCFG_USBPLL_PD |
|
||||
SCB_PDSLEEPCFG_SYSPLL_PD |
|
||||
SCB_PDSLEEPCFG_SYSOSC_PD |
|
||||
SCB_PDSLEEPCFG_ADC_PD |
|
||||
SCB_PDSLEEPCFG_BOD_PD;
|
||||
|
||||
// Enter deep sleep mode (wakeup after 5 seconds)
|
||||
// By default, pin 0.1 is configured as wakeup source
|
||||
pmuDeepSleep(pmuRegVal, 5);
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds)
|
||||
{
|
||||
// Setup the board for deep sleep mode, shutting down certain
|
||||
// peripherals and remapping pins for lower power
|
||||
pmuSetupHW();
|
||||
SCB_PDAWAKECFG = SCB_PDRUNCFG;
|
||||
sleepCtrl |= (1 << 9) | (1 << 11);
|
||||
SCB_PDSLEEPCFG = sleepCtrl;
|
||||
SCB_SCR |= SCB_SCR_SLEEPDEEP;
|
||||
|
||||
/* Configure system to run from WDT and set TMR32B0 for wakeup */
|
||||
if (wakeupSeconds > 0)
|
||||
{
|
||||
// Make sure WDTOSC isn't disabled in PDSLEEPCFG
|
||||
SCB_PDSLEEPCFG &= ~(SCB_PDSLEEPCFG_WDTOSC_PD);
|
||||
|
||||
// Disable 32-bit timer 0 if currently in use
|
||||
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED;
|
||||
|
||||
// Disable internal pullup on 0.1
|
||||
gpioSetPullup(&IOCON_PIO0_1, gpioPullupMode_Inactive);
|
||||
|
||||
/* Enable the clock for CT32B0 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
|
||||
|
||||
/* Configure 0.1 as Timer0_32 MAT2 */
|
||||
IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK;
|
||||
IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2;
|
||||
|
||||
/* Set appropriate timer delay */
|
||||
TMR_TMR32B0MR0 = PMU_WDTCLOCKSPEED_HZ * wakeupSeconds;
|
||||
|
||||
/* Configure match control register to raise an interrupt and reset on MR0 */
|
||||
TMR_TMR32B0MCR |= (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED);
|
||||
|
||||
/* Configure external match register to set 0.1 high on match */
|
||||
TMR_TMR32B0EMR &= ~(0xFF<<4); // Clear EMR config bits
|
||||
TMR_TMR32B0EMR |= TMR_TMR32B0EMR_EMC2_HIGH; // Set MAT2 (0.1) high on match
|
||||
|
||||
/* Enable wakeup interrupts (any I/O pin can be used as a wakeup source) */
|
||||
//NVIC_EnableIRQ(WAKEUP0_IRQn); // P0.0
|
||||
NVIC_EnableIRQ(WAKEUP1_IRQn); // P0.1 (CT32B0_MAT2)
|
||||
//NVIC_EnableIRQ(WAKEUP2_IRQn); // P0.2
|
||||
//NVIC_EnableIRQ(WAKEUP3_IRQn); // P0.3
|
||||
//NVIC_EnableIRQ(WAKEUP4_IRQn); // P0.4
|
||||
//NVIC_EnableIRQ(WAKEUP5_IRQn); // P0.5
|
||||
//NVIC_EnableIRQ(WAKEUP6_IRQn); // P0.6
|
||||
//NVIC_EnableIRQ(WAKEUP7_IRQn); // P0.7
|
||||
//NVIC_EnableIRQ(WAKEUP8_IRQn); // P0.8
|
||||
//NVIC_EnableIRQ(WAKEUP9_IRQn); // P0.9
|
||||
//NVIC_EnableIRQ(WAKEUP10_IRQn); // P0.10
|
||||
//NVIC_EnableIRQ(WAKEUP11_IRQn); // P0.11
|
||||
//NVIC_EnableIRQ(WAKEUP12_IRQn); // P1.0
|
||||
//NVIC_EnableIRQ(WAKEUP13_IRQn); // P1.1
|
||||
//NVIC_EnableIRQ(WAKEUP14_IRQn); // P1.2
|
||||
//NVIC_EnableIRQ(WAKEUP15_IRQn); // P1.3
|
||||
//NVIC_EnableIRQ(WAKEUP16_IRQn); // P1.4
|
||||
//NVIC_EnableIRQ(WAKEUP17_IRQn); // P1.5
|
||||
//NVIC_EnableIRQ(WAKEUP18_IRQn); // P1.6
|
||||
//NVIC_EnableIRQ(WAKEUP19_IRQn); // P1.7
|
||||
//NVIC_EnableIRQ(WAKEUP20_IRQn); // P1.8
|
||||
//NVIC_EnableIRQ(WAKEUP21_IRQn); // P1.9
|
||||
//NVIC_EnableIRQ(WAKEUP22_IRQn); // P1.10
|
||||
//NVIC_EnableIRQ(WAKEUP23_IRQn); // P1.11
|
||||
//NVIC_EnableIRQ(WAKEUP24_IRQn); // P2.0
|
||||
//NVIC_EnableIRQ(WAKEUP25_IRQn); // P2.1
|
||||
//NVIC_EnableIRQ(WAKEUP26_IRQn); // P2.2
|
||||
//NVIC_EnableIRQ(WAKEUP27_IRQn); // P2.3
|
||||
//NVIC_EnableIRQ(WAKEUP28_IRQn); // P2.4
|
||||
//NVIC_EnableIRQ(WAKEUP29_IRQn); // P2.5
|
||||
//NVIC_EnableIRQ(WAKEUP30_IRQn); // P2.6
|
||||
//NVIC_EnableIRQ(WAKEUP31_IRQn); // P2.7
|
||||
//NVIC_EnableIRQ(WAKEUP32_IRQn); // P2.8
|
||||
//NVIC_EnableIRQ(WAKEUP33_IRQn); // P2.9
|
||||
//NVIC_EnableIRQ(WAKEUP34_IRQn); // P2.10
|
||||
//NVIC_EnableIRQ(WAKEUP35_IRQn); // P2.11
|
||||
//NVIC_EnableIRQ(WAKEUP36_IRQn); // P3.0
|
||||
//NVIC_EnableIRQ(WAKEUP37_IRQn); // P3.1
|
||||
//NVIC_EnableIRQ(WAKEUP38_IRQn); // P3.2
|
||||
//NVIC_EnableIRQ(WAKEUP39_IRQn); // P3.3
|
||||
|
||||
/* Use RISING EDGE for wakeup detection. */
|
||||
SCB_STARTAPRP0 |= SCB_STARTAPRP0_APRPIO0_1;
|
||||
|
||||
/* Clear all wakeup sources */
|
||||
SCB_STARTRSRP0CLR = SCB_STARTRSRP0CLR_MASK;
|
||||
|
||||
/* Enable Port 0.1 as wakeup source. */
|
||||
SCB_STARTERP0 |= SCB_STARTERP0_ERPIO0_1;
|
||||
|
||||
// Reconfigure clock to run from WDTOSC
|
||||
pmuWDTClockInit();
|
||||
|
||||
/* Start the timer */
|
||||
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
__asm volatile ("WFI");
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Puts the device in deep power-down mode.
|
||||
|
||||
This function will configure the PMU control register and enter
|
||||
deep power-down mode. Pre-determined values are stored in the four
|
||||
general-purpose registers (PMU_GPREG0..3), which can be used to persist
|
||||
any essential system settings while the device is in deep power-down
|
||||
mode, so long as 3.3V is still available.
|
||||
|
||||
@warning The only way to wake a device up from deep power-down mode
|
||||
is to set a low-level on P1.4. If 3.3V power is lost, the
|
||||
values stored in the four general-purpose registers will
|
||||
also be lost.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/pmu/pmu.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cpuInit();
|
||||
pmuInit();
|
||||
|
||||
// Enter power-down mode
|
||||
pmuPowerDown();
|
||||
|
||||
while(1)
|
||||
{
|
||||
// Device was woken up by WAKEUP pin
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuPowerDown( void )
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
// Make sure HW and external devices are in low power mode
|
||||
pmuSetupHW();
|
||||
|
||||
if ( (PMU_PMUCTRL & ((0x1<<8) | (PMU_PMUCTRL_DPDFLAG))) != 0x0 )
|
||||
{
|
||||
/* Check sleep and deep power down bits. If sleep and/or
|
||||
deep power down mode are entered, clear the PCON bits. */
|
||||
regVal = PMU_PMUCTRL;
|
||||
regVal |= ((0x1<<8) |
|
||||
(PMU_PMUCTRL_DPDEN_SLEEP) |
|
||||
(PMU_PMUCTRL_DPDFLAG));
|
||||
PMU_PMUCTRL = regVal;
|
||||
|
||||
if ( (PMU_GPREG0 != 0x12345678)||(PMU_GPREG1 != 0x87654321)
|
||||
||(PMU_GPREG2 != 0x56781234)||(PMU_GPREG3 != 0x43218765) )
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If in neither sleep nor deep-sleep mode, enter deep power down mode. */
|
||||
PMU_GPREG0 = 0x12345678;
|
||||
PMU_GPREG1 = 0x87654321;
|
||||
PMU_GPREG2 = 0x56781234;
|
||||
PMU_GPREG3 = 0x43218765;
|
||||
SCB_SCR |= SCB_SCR_SLEEPDEEP;
|
||||
PMU_PMUCTRL = PMU_PMUCTRL_DPDEN_DEEPPOWERDOWN;
|
||||
__asm volatile ("WFI");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures parts and system peripherals to use lower power
|
||||
before entering sleep mode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuSetupHW(void)
|
||||
{
|
||||
#ifdef CFG_CHIBI
|
||||
chb_sleep(TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Restores parts and system peripherals to an appropriate
|
||||
state after waking up from deep-sleep mode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pmuRestoreHW(void)
|
||||
{
|
||||
#ifdef CFG_CHIBI
|
||||
// Wakeup Chibi/Transceiver
|
||||
chb_sleep(FALSE);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file pmu.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __PMU_H__
|
||||
#define __PMU_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
void WAKEUP_IRQHandler( void );
|
||||
void pmuInit( void );
|
||||
void pmuSleep( void );
|
||||
void pmuDeepSleep(uint32_t sleepCtrl, uint32_t wakeupSeconds);
|
||||
void pmuPowerDown( void );
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#include "lpc134x.h"
|
||||
#include "sysdefs.h"
|
||||
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
CORE CPU SETTINGS
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_CPU_CCLK Value is for reference only. 'core/cpu/cpu.c' must
|
||||
be modified to change the clock speed, but the value
|
||||
should be indicated here since CFG_CPU_CCLK is used by
|
||||
other peripherals to determine timing.
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_CPU_CCLK (72000000) // 1 tick = 13.88nS
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
SYSTICK TIMER
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_SYSTICK_DELAY_IN_MS The number of milliseconds between each tick
|
||||
of the systick timer.
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_SYSTICK_DELAY_IN_MS (1)
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
SSP
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_SSP0_SCKPIN_2_11 Indicates which pin should be used for SCK0
|
||||
CFG_SSP0_SCKPIN_0_6
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_SSP0_SCKPIN_2_11
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
ON-BOARD LED
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
CFG_LED_PORT The port for the on board LED
|
||||
CFG_LED_PIN The pin for the on board LED
|
||||
CFG_LED_ON The pin state to turn the LED on (0 = low, 1 = high)
|
||||
CFG_LED_OFF The pin state to turn the LED off (0 = low, 1 = high)
|
||||
|
||||
-----------------------------------------------------------------------*/
|
||||
#define CFG_LED_PORT (1)
|
||||
#define CFG_LED_PIN (11)
|
||||
#define CFG_LED_ON (1)
|
||||
#define CFG_LED_OFF (0)
|
||||
|
||||
/*=========================================================================*/
|
|
@ -0,0 +1,254 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file pwm.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@brief Simple PWM example that can be used to control a motor, dim
|
||||
an LED, etc. Uses 16-bit Timer 1 and P1.9 for PWM output.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/pwm/pwm.h"
|
||||
...
|
||||
|
||||
// Initialises PWM output on 16-bit Timer 1 and
|
||||
// sets MAT0 (P1.9) as output
|
||||
pwmInit();
|
||||
|
||||
// Setup the pulse-width and duty-cycle
|
||||
pwmSetDutyCycle(50); // Set 50% duty cycle
|
||||
pwmSetFrequencyInMicroseconds(100); // 100 millisecond pulse width
|
||||
|
||||
// Enable PWM output for exactly 50 pulses
|
||||
pwmStartFixed(50);
|
||||
|
||||
// Alternatively, enable PWM output indefinately
|
||||
pwmStart();
|
||||
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#include "pwm.h"
|
||||
|
||||
uint32_t pwmPulseWidth = CFG_PWM_DEFAULT_PULSEWIDTH;
|
||||
uint32_t pwmDutyCycle = CFG_PWM_DEFAULT_DUTYCYCLE;
|
||||
|
||||
// pwmMaxPulses is used by TIMER16_1_IRQHandler to turn PWM off after
|
||||
// a specified number of pulses have been sent. This only relevant when
|
||||
// pwmStartFixed() is used.
|
||||
volatile uint32_t pwmMaxPulses = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initialises 16-bit Timer 1, and configures the MAT0 output (pin 1.9)
|
||||
to send the PWM output signal.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pwmInit(void)
|
||||
{
|
||||
/* Enable the clock for CT16B1 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1);
|
||||
|
||||
/* Configure PIO1.9 as Timer1_16 MAT0 Output */
|
||||
/* Alternatively, PIO1.10 (MAT1) can also be used though
|
||||
the initialisation code will need to be modified */
|
||||
IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK;
|
||||
IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0;
|
||||
|
||||
/* Set default pulse width (MR3)*/
|
||||
TMR_TMR16B1MR3 = pwmPulseWidth;
|
||||
|
||||
/* Set default duty cycle (MR0) */
|
||||
TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100;
|
||||
|
||||
/* Configure match control register to reset on MR3 */
|
||||
TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR3_RESET_ENABLED);
|
||||
|
||||
/* External Match Register Settings for PWM */
|
||||
TMR_TMR16B1EMR = TMR_TMR16B1EMR_EMC0_TOGGLE | TMR_TMR16B1EMR_EM0;
|
||||
|
||||
/* Disable Timer1 by default (enabled by pwmStart of pwmStartFixed) */
|
||||
TMR_TMR16B1TCR &= ~TMR_TMR16B1TCR_COUNTERENABLE_MASK;
|
||||
|
||||
/* Enable PWM0 and PWM3 */
|
||||
TMR_TMR16B1PWMC = TMR_TMR16B1PWMC_PWM0_ENABLED | TMR_TMR16B1PWMC_PWM3_ENABLED;
|
||||
|
||||
/* Make sure that the timer interrupt is enabled */
|
||||
NVIC_EnableIRQ(TIMER_16_1_IRQn);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Starts the PWM output
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pwmStart(void)
|
||||
{
|
||||
/* Disable interrupt on MR3 in case it was enabled by pwmStartFixed() */
|
||||
TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK);
|
||||
|
||||
/* Enable Timer1 */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Stops the PWM output
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pwmStop(void)
|
||||
{
|
||||
/* Disable Timer1 */
|
||||
TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Starts the PWM output, and stops after the specified number of
|
||||
pulses.
|
||||
|
||||
@param[in] pulses
|
||||
The number of pulses to generate before disabling the
|
||||
PWM output. The output is actually disabled in the
|
||||
timer ISR.
|
||||
|
||||
@warning The PWM output is actually stopped inside the 16-bit
|
||||
timer ISR in "core/timer16/timer16.h".
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void pwmStartFixed(uint32_t pulses)
|
||||
{
|
||||
pwmMaxPulses = pulses;
|
||||
|
||||
/* Configure match control register to also raise an interrupt on MR3 */
|
||||
TMR_TMR16B1MCR |= (TMR_TMR16B1MCR_MR3_INT_ENABLED);
|
||||
|
||||
/* Enable Timer1 (it will eventually be disabled in the ISR) */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Sets the signal's duty cycle in percent (1-100).
|
||||
|
||||
@param[in] percentage
|
||||
The duty-cycle in percentage (the amount of time that
|
||||
the signal is 'high' relative to the time its 'low').
|
||||
|
||||
@returns -1 if an invalid percentage was supplied. Value must be
|
||||
between 1 and 100.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int pwmSetDutyCycle(uint32_t percentage)
|
||||
{
|
||||
if ((percentage < 1) || (percentage > 100))
|
||||
{
|
||||
/* Duty Cycle must be a value between 1 and 100 */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set Duty Cycle (MR0) */
|
||||
TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - (pwmDutyCycle = percentage))) / 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Sets the signal's frequency/pulse-width to the specified number
|
||||
of ticks.
|
||||
|
||||
@param[in] ticks
|
||||
The duration in clock ticks of each full pulse.
|
||||
|
||||
@returns -1 if a zero-value was provided for ticks.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int pwmSetFrequencyInTicks(uint16_t ticks)
|
||||
{
|
||||
if (ticks < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set Pulse Width (MR3)*/
|
||||
TMR_TMR16B1MR3 = (pwmPulseWidth = ticks);
|
||||
|
||||
/* Adjust Duty Cycle (MR0) */
|
||||
TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Sets the signal's frequency/pulse-width to the specified number
|
||||
of microseconds.
|
||||
|
||||
@param[in] us
|
||||
The duration in microseconds of each full pulse.
|
||||
|
||||
@returns -1 if the supplied value exceeds the limits of the 16-bit
|
||||
timer, or if a zero-value was provided.
|
||||
|
||||
@Warning Because a 16-bit timer is used here by default, the
|
||||
maximum frequency is quite small. Running at 36MHz, the
|
||||
largest possible pulse-width/frequency is ~1,82mS or
|
||||
1820 microSeconds. At 12MHz its 5461 uS, and at 48MHz
|
||||
its 1365 uS.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int pwmSetFrequencyInMicroseconds(uint16_t us)
|
||||
{
|
||||
if (us < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ticks = (((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000) * us);
|
||||
if (ticks > 0xFFFF)
|
||||
{
|
||||
/* Delay exceeds the upper limit for the 16-bit timer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set Pulse Width (MR3)*/
|
||||
TMR_TMR16B1MR3 = (pwmPulseWidth = ticks);
|
||||
|
||||
/* Adjust Duty Cycle (MR0) */
|
||||
TMR_TMR16B1MR0 = (pwmPulseWidth * (100 - pwmDutyCycle)) / 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file pwm.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _PWM_H_
|
||||
#define _PWM_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
void pwmInit( void );
|
||||
void pwmStart( void );
|
||||
void pwmStop( void );
|
||||
void pwmStartFixed( uint32_t pulses );
|
||||
int pwmSetDutyCycle( uint32_t percentage );
|
||||
int pwmSetFrequencyInTicks( uint16_t ticks );
|
||||
int pwmSetFrequencyInMicroseconds(uint16_t us );
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file rom_drivers.h
|
||||
@author NXP Semiconductor
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef ROM_DRIVERS_H_
|
||||
#define ROM_DRIVERS_H_
|
||||
|
||||
#include "sysdefs.h"
|
||||
|
||||
typedef struct _USB_DEVICE_INFO
|
||||
{
|
||||
uint16_t DevType;
|
||||
uint32_t DevDetailPtr;
|
||||
} USB_DEV_INFO;
|
||||
|
||||
typedef struct _USBD
|
||||
{
|
||||
void (*init_clk_pins)(void);
|
||||
void (*isr)(void);
|
||||
void (*init)( USB_DEV_INFO * DevInfoPtr );
|
||||
void (*connect)(uint32_t con);
|
||||
} USBD;
|
||||
|
||||
typedef struct _ROM
|
||||
{
|
||||
const USBD * pUSBD;
|
||||
} ROM;
|
||||
|
||||
typedef struct _MSC_DEVICE_INFO {
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint32_t StrDescPtr;
|
||||
uint32_t MSCInquiryStr;
|
||||
uint32_t BlockCount;
|
||||
uint32_t BlockSize;
|
||||
uint32_t MemorySize;
|
||||
void (*MSC_Write)( uint32_t offset, uint8_t src[], uint32_t length);
|
||||
void (*MSC_Read)( uint32_t offset, uint8_t dst[], uint32_t length);
|
||||
} MSC_DEVICE_INFO;
|
||||
|
||||
typedef struct _HID_DEVICE_INFO
|
||||
{
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint32_t StrDescPtr;
|
||||
uint8_t InReportCount;
|
||||
uint8_t OutReportCount;
|
||||
uint8_t SampleInterval;
|
||||
void (*InReport)(uint8_t src[], uint32_t length);
|
||||
void (*OutReport)(uint8_t dst[], uint32_t length);
|
||||
} HID_DEVICE_INFO;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,299 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file ssp.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Generic code for SSP/SPI communications. By default, the SSP block
|
||||
is initialised in SPI master mode.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/ssp/ssp.h"
|
||||
...
|
||||
cpuInit();
|
||||
sspInit(0, sspClockPolarity_High, sspClockPhase_RisingEdge);
|
||||
...
|
||||
uint8_t request[SSP_FIFOSIZE];
|
||||
uint8_t response[SSP_FIFOSIZE];
|
||||
|
||||
// Send 0x9C to the slave device and wait for a response
|
||||
request[0] = 0x80 | 0x1C;
|
||||
// Toggle the select pin
|
||||
ssp0Select();
|
||||
// Send 1 byte from the request buffer
|
||||
sspSend(0, (uint8_t *)&request, 1);
|
||||
// Receive 1 byte into the response buffer
|
||||
sspReceive(0, (uint8_t *)&response, 1);
|
||||
// Reset the select pin
|
||||
ssp0Deselect();
|
||||
// Print the results
|
||||
debug_printf("Ox%x ", response[0]);
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#include "ssp.h"
|
||||
#include "core/gpio/gpio.h"
|
||||
|
||||
/* Statistics for all interrupts */
|
||||
volatile uint32_t interruptRxStat = 0;
|
||||
volatile uint32_t interruptOverRunStat = 0;
|
||||
volatile uint32_t interruptRxTimeoutStat = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief SSP0 interrupt handler for SPI communication
|
||||
|
||||
The algorithm is, if RXFIFO is at least half full,
|
||||
start receive until it's empty; if TXFIFO is at least
|
||||
half empty, start transmit until it's full.
|
||||
This will maximize the use of both FIFOs and performance.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SSP_IRQHandler (void)
|
||||
{
|
||||
uint32_t regValue;
|
||||
|
||||
regValue = SSP_SSP0MIS;
|
||||
|
||||
/* Check for overrun interrupt */
|
||||
if ( regValue & SSP_SSP0MIS_RORMIS_FRMRCVD )
|
||||
{
|
||||
interruptOverRunStat++;
|
||||
SSP_SSP0ICR = SSP_SSP0ICR_RORIC_CLEAR; // Clear interrupt
|
||||
}
|
||||
|
||||
/* Check for timeout interrupt */
|
||||
if ( regValue & SSP_SSP0MIS_RTMIS_NOTEMPTY )
|
||||
{
|
||||
interruptRxTimeoutStat++;
|
||||
SSP_SSP0ICR = SSP_SSP0ICR_RTIC_CLEAR; // Clear interrupt
|
||||
}
|
||||
|
||||
/* Check if Rx buffer is at least half-full */
|
||||
if ( regValue & SSP_SSP0MIS_RXMIS_HALFFULL )
|
||||
{
|
||||
// ToDo: Receive until it's empty
|
||||
interruptRxStat++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the SSP0 port
|
||||
|
||||
By default, SSP0 is set to SPI frame-format with 8-bit data. Pin 2.11
|
||||
is routed to serve as serial clock (SCK), and SSEL (0.2) is set to
|
||||
GPIO to allow manual control of when the SPI port is enabled or
|
||||
disabled. Overrun and timeout interrupts are both enabled.
|
||||
|
||||
@param[in] portNum
|
||||
The SPI port to use (0..1)
|
||||
@param[in] polarity
|
||||
Indicates whether the clock should be held high
|
||||
(sspClockPolarity_High) or low (sspClockPolarity_Low)
|
||||
when inactive.
|
||||
@param[in] phase
|
||||
Indicates whether new bits start on the leading
|
||||
(sspClockPhase_RisingEdge) or falling
|
||||
(sspClockPhase_FallingEdge) edge of clock transitions.
|
||||
|
||||
@note sspSelect() and sspDeselect() macros have been defined in
|
||||
ssp.h to control the SSEL line without having to know the
|
||||
specific pin being used.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase)
|
||||
{
|
||||
gpioInit();
|
||||
|
||||
if (portNum == 0)
|
||||
{
|
||||
/* Reset SSP */
|
||||
SCB_PRESETCTRL &= ~SCB_PRESETCTRL_SSP0_MASK;
|
||||
SCB_PRESETCTRL |= SCB_PRESETCTRL_SSP0_RESETDISABLED;
|
||||
|
||||
/* Enable AHB clock to the SSP domain. */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_SSP0);
|
||||
|
||||
/* Divide by 1 (SSPCLKDIV also enables to SSP CLK) */
|
||||
SCB_SSP0CLKDIV = SCB_SSP0CLKDIV_DIV1;
|
||||
|
||||
/* Set P0.8 to SSP MISO */
|
||||
IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK;
|
||||
IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_MISO0;
|
||||
|
||||
/* Set P0.9 to SSP MOSI */
|
||||
IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK;
|
||||
IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_MOSI0;
|
||||
|
||||
/* Set 2.11 to SSP SCK (0.6 and 0.10 can also be used) */
|
||||
#ifdef CFG_SSP0_SCKPIN_2_11
|
||||
IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO2_11;
|
||||
IOCON_PIO2_11 = IOCON_PIO2_11_FUNC_SCK0;
|
||||
#endif
|
||||
|
||||
/* Set 0.6 to SSP SCK (2.11 and 0.10 can also be used) */
|
||||
#ifdef CFG_SSP0_SCKPIN_0_6
|
||||
IOCON_SCKLOC = IOCON_SCKLOC_SCKPIN_PIO0_6;
|
||||
IOCON_PIO0_6 = IOCON_PIO0_6_FUNC_SCK;
|
||||
#endif
|
||||
|
||||
/* Set P0.2/SSEL to GPIO output and high */
|
||||
IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK;
|
||||
IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_GPIO;
|
||||
gpioSetDir(SSP0_CSPORT, SSP0_CSPIN, 1);
|
||||
gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1);
|
||||
gpioSetPullup(&IOCON_PIO0_2, gpioPullupMode_Inactive); // Board has external pull-up
|
||||
|
||||
/* If SSP0CLKDIV = DIV1 -- (PCLK / (CPSDVSR × [SCR+1])) = (72,000,000 / (2 x [8 + 1])) = 4.0 MHz */
|
||||
uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit
|
||||
| SSP_SSP0CR0_FRF_SPI // Frame format = SPI
|
||||
| SSP_SSP0CR0_SCR_8); // Serial clock rate = 8
|
||||
|
||||
// Set clock polarity
|
||||
if (polarity == sspClockPolarity_High)
|
||||
configReg |= SSP_SSP0CR0_CPOL_HIGH; // Clock polarity = High between frames
|
||||
else
|
||||
configReg &= ~SSP_SSP0CR0_CPOL_MASK; // Clock polarity = Low between frames
|
||||
|
||||
// Set edge transition
|
||||
if (phase == sspClockPhase_FallingEdge)
|
||||
configReg |= SSP_SSP0CR0_CPHA_SECOND; // Clock out phase = Trailing edge clock transition
|
||||
else
|
||||
configReg &= ~SSP_SSP0CR0_CPHA_MASK; // Clock out phase = Leading edge clock transition
|
||||
|
||||
// Assign config values to SSP0CR0
|
||||
SSP_SSP0CR0 = configReg;
|
||||
|
||||
/* Clock prescale register must be even and at least 2 in master mode */
|
||||
SSP_SSP0CPSR = SSP_SSP0CPSR_CPSDVSR_DIV2;
|
||||
|
||||
/* Clear the Rx FIFO */
|
||||
uint8_t i, Dummy=Dummy;
|
||||
for ( i = 0; i < SSP_FIFOSIZE; i++ )
|
||||
{
|
||||
Dummy = SSP_SSP0DR;
|
||||
}
|
||||
|
||||
/* Enable the SSP Interrupt */
|
||||
NVIC_EnableIRQ(SSP_IRQn);
|
||||
|
||||
/* Set SSPINMS registers to enable interrupts
|
||||
* enable all error related interrupts */
|
||||
SSP_SSP0IMSC = ( SSP_SSP0IMSC_RORIM_ENBL // Enable overrun interrupt
|
||||
| SSP_SSP0IMSC_RTIM_ENBL); // Enable timeout interrupt
|
||||
|
||||
/* Enable device and set it to master mode, no loopback */
|
||||
SSP_SSP0CR1 = SSP_SSP0CR1_SSE_ENABLED | SSP_SSP0CR1_MS_MASTER | SSP_SSP0CR1_LBM_NORMAL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends a block of data to the SSP0 port
|
||||
|
||||
@param[in] portNum
|
||||
The SPI port to use (0..1)
|
||||
@param[in] buf
|
||||
Pointer to the data buffer
|
||||
@param[in] length
|
||||
Block length of the data buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t Dummy = Dummy;
|
||||
|
||||
if (portNum == 0)
|
||||
{
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
/* Move on only if NOT busy and TX FIFO not full. */
|
||||
while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL);
|
||||
SSP_SSP0DR = *buf;
|
||||
buf++;
|
||||
|
||||
while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY );
|
||||
/* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
|
||||
on MISO. Otherwise, when SSP0Receive() is called, previous data byte
|
||||
is left in the FIFO. */
|
||||
Dummy = SSP_SSP0DR;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Receives a block of data from the SSP0 port
|
||||
|
||||
@param[in] portNum
|
||||
The SPI port to use (0..1)
|
||||
@param[in] buf
|
||||
Pointer to the data buffer
|
||||
@param[in] length
|
||||
Block length of the data buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void sspReceive(uint8_t portNum, uint8_t *buf, uint32_t length)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (portNum == 0)
|
||||
{
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
/* As long as the receive FIFO is not empty, data can be received. */
|
||||
SSP_SSP0DR = 0xFF;
|
||||
|
||||
/* Wait until the Busy bit is cleared */
|
||||
while ( (SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY );
|
||||
|
||||
*buf = SSP_SSP0DR;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file ssp.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _SSP_H_
|
||||
#define _SSP_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
#include "core/gpio/gpio.h"
|
||||
|
||||
#define SSP_FIFOSIZE 8 /* SPI read and write buffer size */
|
||||
#define SSP_MAX_TIMEOUT 0xFF
|
||||
|
||||
#define SSP0_CSPORT 0
|
||||
#define SSP0_CSPIN 2
|
||||
|
||||
/* Macro definitions to enable and disable SPI */
|
||||
#define ssp0Select() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 0);} while (0)
|
||||
#define ssp0Deselect() do {gpioSetValue(SSP0_CSPORT, SSP0_CSPIN, 1);} while (0)
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Indicates whether the clock should be high or low between frames.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum sspClockPolarity_e
|
||||
{
|
||||
sspClockPolarity_Low = 0,
|
||||
sspClockPolarity_High
|
||||
}
|
||||
sspClockPolarity_t;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Indicates whether the bits start at the rising or falling edge of
|
||||
the clock transition.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
typedef enum sspClockPhase_e
|
||||
{
|
||||
sspClockPhase_RisingEdge = 0,
|
||||
sspClockPhase_FallingEdge
|
||||
}
|
||||
sspClockPhase_t;
|
||||
|
||||
extern void SSP_IRQHandler (void);
|
||||
void sspInit (uint8_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase);
|
||||
void sspSend (uint8_t portNum, uint8_t *buf, uint32_t length);
|
||||
void sspReceive (uint8_t portNum, uint8_t *buf, uint32_t length);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,65 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file sysdefs.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _SYSDEFS_H_
|
||||
#define _SYSDEFS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Stay compatible with ugly "windows" style
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
typedef volatile uint8_t REG8;
|
||||
typedef volatile uint16_t REG16;
|
||||
typedef volatile uint32_t REG32;
|
||||
typedef unsigned char byte_t;
|
||||
|
||||
#define pREG8 (REG8 *)
|
||||
#define pREG16 (REG16 *)
|
||||
#define pREG32 (REG32 *)
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file sysinit.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sysinit.h"
|
||||
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/pmu/pmu.h"
|
||||
#include "core/adc/adc.h"
|
||||
|
||||
#ifdef CFG_PRINTF_UART
|
||||
#include "core/uart/uart.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_INTERFACE
|
||||
#include "core/cmd/cmd.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CHIBI
|
||||
#include "drivers/chibi/chb.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_USBHID
|
||||
#include "core/usbhid-rom/usbhid.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_USBCDC
|
||||
volatile unsigned int lastTick;
|
||||
#include "core/usbcdc/usb.h"
|
||||
#include "core/usbcdc/usbcore.h"
|
||||
#include "core/usbcdc/usbhw.h"
|
||||
#include "core/usbcdc/cdcuser.h"
|
||||
#include "core/usbcdc/cdc_buf.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_ST7565
|
||||
#include "drivers/lcd/bitmap/st7565/st7565.h"
|
||||
#include "drivers/lcd/smallfonts.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_SSD1306
|
||||
#include "drivers/lcd/bitmap/ssd1306/ssd1306.h"
|
||||
#include "drivers/lcd/smallfonts.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_TFTLCD
|
||||
#include "drivers/lcd/tft/lcd.h"
|
||||
#include "drivers/lcd/tft/touchscreen.h"
|
||||
#include "drivers/lcd/tft/drawing.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_I2CEEPROM
|
||||
#include "drivers/eeprom/mcp24aa/mcp24aa.h"
|
||||
#include "drivers/eeprom/eeprom.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_PWM
|
||||
#include "core/pwm/pwm.h"
|
||||
#endif
|
||||
|
||||
#ifdef CFG_SDCARD
|
||||
#include "core/ssp/ssp.h"
|
||||
#include "drivers/fatfs/diskio.h"
|
||||
#include "drivers/fatfs/ff.h"
|
||||
|
||||
DWORD get_fattime ()
|
||||
{
|
||||
// ToDo!
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Configures the core system clock and sets up any mandatory
|
||||
peripherals like the systick timer, UART for printf, etc.
|
||||
|
||||
This function should set the HW to the default state you wish to be
|
||||
in coming out of reset/startup, such as disabling or enabling LEDs,
|
||||
setting specific pin states, etc.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void systemInit()
|
||||
{
|
||||
cpuInit(); // Configure the CPU
|
||||
systickInit(CFG_SYSTICK_DELAY_IN_MS); // Start systick timer
|
||||
gpioInit(); // Enable GPIO
|
||||
pmuInit(); // Configure power management
|
||||
adcInit(); // Config adc pins to save power
|
||||
|
||||
// Set LED pin as output and turn LED off
|
||||
gpioSetDir(CFG_LED_PORT, CFG_LED_PIN, 1);
|
||||
gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF);
|
||||
|
||||
// Initialise EEPROM
|
||||
#ifdef CFG_I2CEEPROM
|
||||
mcp24aaInit();
|
||||
#endif
|
||||
|
||||
// Initialise UART with the default baud rate
|
||||
#ifdef CFG_PRINTF_UART
|
||||
uint32_t uart = eepromReadU32(CFG_EEPROM_UART_SPEED);
|
||||
if ((uart == 0xFFFFFFFF) || (uart > 115200))
|
||||
{
|
||||
uartInit(CFG_UART_BAUDRATE); // Use default baud rate
|
||||
}
|
||||
else
|
||||
{
|
||||
uartInit(uart); // Use baud rate from EEPROM
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialise PWM (requires 16-bit Timer 1 and P1.9)
|
||||
#ifdef CFG_PWM
|
||||
pwmInit();
|
||||
#endif
|
||||
|
||||
// Initialise USB HID
|
||||
#ifdef CFG_USBHID
|
||||
usbHIDInit();
|
||||
#endif
|
||||
|
||||
// Initialise USB CDC
|
||||
#ifdef CFG_USBCDC
|
||||
lastTick = systickGetTicks(); // Used to control output/printf timing
|
||||
CDC_Init(); // Initialise VCOM
|
||||
USB_Init(); // USB Initialization
|
||||
USB_Connect(TRUE); // USB Connect
|
||||
// Wait until USB is configured or timeout occurs
|
||||
uint32_t usbTimeout = 0;
|
||||
while ( usbTimeout < CFG_USBCDC_INITTIMEOUT / 10 )
|
||||
{
|
||||
if (USB_Configuration) break;
|
||||
systickDelay(10); // Wait 10ms
|
||||
usbTimeout++;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Printf can now be used with UART or USBCDC
|
||||
|
||||
// Initialise the ST7565 128x64 pixel display
|
||||
#ifdef CFG_ST7565
|
||||
st7565Init();
|
||||
st7565ClearScreen(); // Clear the screen
|
||||
st7565Backlight(1); // Enable the backlight
|
||||
#endif
|
||||
|
||||
// Initialise the SSD1306 OLED display
|
||||
#ifdef CFG_SSD1306
|
||||
ssd1306Init(SSD1306_SWITCHCAPVCC);
|
||||
ssd1306ClearScreen(); // Clear the screen
|
||||
#endif
|
||||
|
||||
// Initialise TFT LCD Display
|
||||
#ifdef CFG_TFTLCD
|
||||
lcdInit();
|
||||
#endif
|
||||
|
||||
// Initialise Chibi
|
||||
// Warning: CFG_CHIBI must be disabled if no antenna is connected,
|
||||
// otherwise the SW will halt during initialisation
|
||||
#ifdef CFG_CHIBI
|
||||
// Write addresses to EEPROM for the first time if necessary
|
||||
// uint16_t addr_short = 0x0025;
|
||||
// uint64_t addr_ieee = 0x0000000000000025;
|
||||
// mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t *)&addr_short, 2);
|
||||
// mcp24aaWriteBuffer(CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t *)&addr_ieee, 8);
|
||||
chb_init();
|
||||
// chb_pcb_t *pcb = chb_get_pcb();
|
||||
// printf("%-40s : 0x%04X%s", "Chibi Initialised", pcb->src_addr, CFG_PRINTF_NEWLINE);
|
||||
#endif
|
||||
|
||||
// Start the command line interface
|
||||
#ifdef CFG_INTERFACE
|
||||
cmdInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends a single byte to a pre-determined peripheral (UART, etc.).
|
||||
|
||||
@param[in] byte
|
||||
Byte value to send
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void __putchar(const char c)
|
||||
{
|
||||
#ifdef CFG_PRINTF_UART
|
||||
// Send output to UART
|
||||
uartSendByte(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CFG_USBCDC
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends a string to a pre-determined end point (UART, etc.).
|
||||
|
||||
@param[in] str
|
||||
Text to send
|
||||
|
||||
@note This function is only called when using the GCC-compiler
|
||||
in Codelite or running the Makefile manually. This function
|
||||
will not be called when using the C library in Crossworks for
|
||||
ARM.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int puts(const char * str)
|
||||
{
|
||||
// There must be at least 1ms between USB frames (of up to 64 bytes)
|
||||
// This buffers all data and writes it out from the buffer one frame
|
||||
// and one millisecond at a time
|
||||
#ifdef CFG_PRINTF_USBCDC
|
||||
if (USB_Configuration)
|
||||
{
|
||||
while(*str)
|
||||
cdcBufferWrite(*str++);
|
||||
// Check if we can flush the buffer now or if we need to wait
|
||||
unsigned int currentTick = systickGetTicks();
|
||||
if (currentTick != lastTick)
|
||||
{
|
||||
uint8_t frame[64];
|
||||
uint32_t bytesRead = 0;
|
||||
while (cdcBufferDataPending())
|
||||
{
|
||||
// Read up to 64 bytes as long as possible
|
||||
bytesRead = cdcBufferReadLen(frame, 64);
|
||||
USB_WriteEP (CDC_DEP_IN, frame, bytesRead);
|
||||
systickDelay(1);
|
||||
}
|
||||
lastTick = currentTick;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Handle output character by character in __putchar
|
||||
while(*str) __putchar(*str++);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file sysinit.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __SYSINIT_H__
|
||||
#define __SYSINIT_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#include "core/gpio/gpio.h"
|
||||
#include "core/systick/systick.h"
|
||||
|
||||
// Function prototypes
|
||||
void systemInit();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,229 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file systick.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Controls the 24-bit 'system tick' clock, which can be used as a
|
||||
generic timer or to control time sharing with an embedded real-time
|
||||
operating system (such as FreeRTOS).
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/systick/systick.h"
|
||||
|
||||
void main (void)
|
||||
{
|
||||
cpuInit();
|
||||
|
||||
// Start systick timer with one tick every 10ms
|
||||
systickInit(10);
|
||||
|
||||
while(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "systick.h"
|
||||
|
||||
#ifdef CFG_SDCARD
|
||||
#include "drivers/fatfs/diskio.h"
|
||||
volatile uint32_t fatTicks = 0;
|
||||
#endif
|
||||
|
||||
volatile uint32_t systickTicks = 0; // 1ms tick counter
|
||||
volatile uint32_t systickRollovers = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Systick interrupt handler
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SysTick_Handler (void)
|
||||
{
|
||||
systickTicks++;
|
||||
|
||||
// Increment rollover counter
|
||||
if (systickTicks == 0xFFFFFFFF) systickRollovers++;
|
||||
|
||||
#ifdef CFG_SDCARD
|
||||
fatTicks++;
|
||||
if (fatTicks == 10)
|
||||
{
|
||||
fatTicks = 0;
|
||||
disk_timerproc();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Configures the systick timer
|
||||
|
||||
@param[in] ticks
|
||||
The number of clock cycles between each tick of the
|
||||
systick timer. for example, 'CFG_CPU_CCLK / 1000' =
|
||||
1 millisecond. This value must not exceed 0x00FFFFFF.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static uint32_t systickConfig(uint32_t ticks)
|
||||
{
|
||||
// Check if 'ticks' is greater than maximum value
|
||||
if (ticks > SYSTICK_STRELOAD_MASK)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
// Reset counter
|
||||
systickTicks = 0;
|
||||
|
||||
// Set reload register
|
||||
SYSTICK_STRELOAD = (ticks & SYSTICK_STRELOAD_MASK) - 1;
|
||||
|
||||
// Load the systick counter value
|
||||
SYSTICK_STCURR = 0;
|
||||
|
||||
// Enable systick IRQ and timer
|
||||
SYSTICK_STCTRL = SYSTICK_STCTRL_CLKSOURCE |
|
||||
SYSTICK_STCTRL_TICKINT |
|
||||
SYSTICK_STCTRL_ENABLE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the systick timer
|
||||
|
||||
@param[in] delayMs
|
||||
The number of milliseconds between each tick of the systick
|
||||
timer.
|
||||
|
||||
@note The shortest possible delay is 1 millisecond, which will
|
||||
allow fine grained delays, but will cause more load on the
|
||||
system than a 10mS delay. The resolution of the systick
|
||||
timer needs to be balanced with the amount of processing
|
||||
time you can spare. The delay should really only be set
|
||||
to 1 mS if you genuinely have a need for 1mS delays,
|
||||
otherwise a higher value like 5 or 10 mS is probably
|
||||
more appropriate.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void systickInit (uint32_t delayMs)
|
||||
{
|
||||
systickConfig ((CFG_CPU_CCLK / 1000) * delayMs);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Causes a blocking delay for 'delayTicks' ticks on the
|
||||
systick timer. For example: systickDelay(100) would cause
|
||||
a blocking delay for 100 ticks of the systick timer.
|
||||
|
||||
@param[in] delayTicks
|
||||
The number of systick ticks to cause a blocking delay for
|
||||
|
||||
@Note This function takes into account the fact that the tick
|
||||
counter may eventually roll over to 0 once it reaches
|
||||
0xFFFFFFFF.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void systickDelay (uint32_t delayTicks)
|
||||
{
|
||||
uint32_t curTicks;
|
||||
curTicks = systickTicks;
|
||||
|
||||
// Make sure delay is at least 1 tick in case of division, etc.
|
||||
if (delayTicks == 0) delayTicks = 1;
|
||||
|
||||
if (curTicks > 0xFFFFFFFF - delayTicks)
|
||||
{
|
||||
// Rollover will occur during delay
|
||||
while (systickTicks >= curTicks)
|
||||
{
|
||||
while (systickTicks < (delayTicks - (0xFFFFFFFF - curTicks)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((systickTicks - curTicks) < delayTicks);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Returns the current value of the systick timer counter.
|
||||
This value is incremented by one every time an interrupt
|
||||
fires for the systick timer.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t systickGetTicks(void)
|
||||
{
|
||||
return systickTicks;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Returns the current value of the systick timer rollover
|
||||
counter. This value is incremented by one every time the
|
||||
tick counter rolls over from 0xFFFFFFFF to 0.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t systickGetRollovers(void)
|
||||
{
|
||||
return systickRollovers;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Returns the approximate number of seconds that the
|
||||
systick timer has been running.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t systickGetSecondsActive(void)
|
||||
{
|
||||
uint32_t currentTick = systickTicks;
|
||||
uint32_t rollovers = systickRollovers;
|
||||
uint32_t secsActive = currentTick / (1000 / CFG_SYSTICK_DELAY_IN_MS);
|
||||
secsActive += rollovers * (0xFFFFFFFF / (1000 / CFG_SYSTICK_DELAY_IN_MS));
|
||||
|
||||
return secsActive;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file systick.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _SYSTICK_H_
|
||||
#define _SYSTICK_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
void systickInit (uint32_t delayMs);
|
||||
void systickDelay (uint32_t delayTicks);
|
||||
uint32_t systickGetTicks(void);
|
||||
uint32_t systickGetRollovers(void);
|
||||
uint32_t systickGetSecondsActive(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,505 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file timer16.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Generic code for both 16-bit timers.
|
||||
|
||||
@warning 16-bit timers are limited to roughly ~0.91ms (or 910uS) on
|
||||
a system running at 72MHz since:
|
||||
@code
|
||||
1 mS = CFG_CPU_CCLK / 1000
|
||||
= 72000000 / 1000
|
||||
= 72000 'ticks'
|
||||
@endcode
|
||||
Meaning that 0xFFFF (65535) 'ticks' = 0.910208 milliseconds
|
||||
or 910 microseconds.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "/core/cpu/cpu.h"
|
||||
#include "/core/timer16/timer16.h"
|
||||
|
||||
// Instantiated in timer16.h
|
||||
extern volatile uint32_t timer16_0_counter;
|
||||
...
|
||||
cpuInit();
|
||||
|
||||
// Initialise timer0 with a delay of 0xFFFF, which will cause the
|
||||
// timer interrupt to fire every 65535 ticks and increment
|
||||
// timer16_0_counter by 1
|
||||
timer16Init(0, 0xFFFF);
|
||||
|
||||
// Enable the timer
|
||||
timer16Enable(0);
|
||||
|
||||
// At this point timer16_0_counter should start incrementing by 1
|
||||
// every 65535 ticks
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "timer16.h"
|
||||
|
||||
volatile uint32_t timer16_0_counter = 0;
|
||||
volatile uint32_t timer16_1_counter = 0;
|
||||
|
||||
#ifdef CFG_PWM
|
||||
volatile uint32_t pwmCounter = 0;
|
||||
extern volatile uint32_t pwmMaxPulses; // See drivers/pwm/pwm.c
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Causes a blocking delay for the specified number of
|
||||
clock ticks.
|
||||
|
||||
@note The exact duration of this delay depends on the speed of the
|
||||
system clock, but it will invariably be short because of the
|
||||
16-bit limitation. For example, on a system with a 72MHz
|
||||
clock, a 1mS delay would be equal to 72,000 ticks, which is
|
||||
already above the maximum 16-bit value of 65,535. Thus, the
|
||||
maximum delay measured in mS with a 72MHz clock is ~0.91mS.
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to user (0..1)
|
||||
@param[in] delayInTicks
|
||||
The number of clock ticks to delay (0..65534)
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "/core/cpu/cpu.h"
|
||||
#include "/core/timer16/timer16.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cpuInit();
|
||||
|
||||
// Initialise timer 0 ... delay is provided but not used here
|
||||
timer16Init(0, 0xFFFF);
|
||||
|
||||
// Enable the timer
|
||||
timer16Enable(0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
// Cause blocking delay for 36000 ticks (0.5mS @ 72MHz)
|
||||
// Note: The delay must be 65534 or less (16-bit value)
|
||||
timer16DelayTicks(0, 36000);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks)
|
||||
{
|
||||
// ToDo: Verify incoming value
|
||||
|
||||
if (timerNum == 0)
|
||||
{
|
||||
/* Reset the timer */
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED;
|
||||
|
||||
/* Set the prescaler to zero */
|
||||
TMR_TMR16B0PR = 0x00;
|
||||
|
||||
TMR_TMR16B0MR0 = delayInTicks;
|
||||
|
||||
/* Reset all interrupts */
|
||||
TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL;
|
||||
|
||||
/* Stop timer on match (MR0) */
|
||||
TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED;
|
||||
|
||||
/* Start timer */
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED;
|
||||
|
||||
/* Wait until the delay time has elapsed */
|
||||
while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED);
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
/* Reset the timer */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED;
|
||||
|
||||
/* Set the prescaler to zero */
|
||||
TMR_TMR16B1PR = 0x00;
|
||||
|
||||
TMR_TMR16B1MR0 = delayInTicks;
|
||||
|
||||
/* Reset all interrupts */
|
||||
TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL;
|
||||
|
||||
/* Stop timer on match (MR0) */
|
||||
TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED;
|
||||
|
||||
/* Start timer */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED;
|
||||
|
||||
/* Wait until the delay time has elapsed */
|
||||
while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Causes a blocking delay for the specified number of
|
||||
microseconds
|
||||
|
||||
@warning The maximum delay in uS will depend on the clock speed,
|
||||
but running at 72MHz the maximum delay (MR = 0xFFFF)
|
||||
would be 910uS (0xFFFF / 72 = 910), or 0.91 milliseconds.
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to user (0..1)
|
||||
@param[in] delayInUs
|
||||
The number of microseconds to wait
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "/core/cpu/cpu.h"
|
||||
#include "/core/timer16/timer16.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cpuInit();
|
||||
|
||||
// Initialise timer 0 ... delay is provided but not used here
|
||||
timer16Init(0, 0xFFFF);
|
||||
|
||||
// Enable the timer
|
||||
timer16Enable(0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
// Cause blocking delay for 500 microseconds (0.5mS)
|
||||
timer16DelayUS(0, 500);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS)
|
||||
{
|
||||
// ToDo: Check if the appropriate timer is enabled first?
|
||||
|
||||
if (timerNum == 0)
|
||||
{
|
||||
/* Reset the timer */
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERRESET_ENABLED;
|
||||
|
||||
/* Set the prescaler to zero */
|
||||
TMR_TMR16B0PR = 0x00;
|
||||
|
||||
TMR_TMR16B0MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000);
|
||||
|
||||
/* Reset all interrupts */
|
||||
TMR_TMR16B0IR = TMR_TMR16B0IR_MASK_ALL;
|
||||
|
||||
/* Stop timer on match (MR0) */
|
||||
TMR_TMR16B0MCR = TMR_TMR16B0MCR_MR0_STOP_ENABLED;
|
||||
|
||||
/* Start timer */
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED;
|
||||
|
||||
/* Wait until the delay time has elapsed */
|
||||
while (TMR_TMR16B0TCR & TMR_TMR16B0TCR_COUNTERENABLE_ENABLED);
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
/* Reset the timer */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERRESET_ENABLED;
|
||||
|
||||
/* Set the prescaler to zero */
|
||||
TMR_TMR16B1PR = 0x00;
|
||||
|
||||
TMR_TMR16B1MR0 = delayInUS * ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)/1000000);
|
||||
|
||||
/* Reset all interrupts */
|
||||
TMR_TMR16B1IR = TMR_TMR16B1IR_MASK_ALL;
|
||||
|
||||
/* Stop timer on match (MR0) */
|
||||
TMR_TMR16B1MCR = TMR_TMR16B1MCR_MR0_STOP_ENABLED;
|
||||
|
||||
/* Start timer */
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED;
|
||||
|
||||
/* Wait until the delay time has elapsed */
|
||||
while (TMR_TMR16B1TCR & TMR_TMR16B1TCR_COUNTERENABLE_ENABLED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Interrupt handler for 16-bit timer 0
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void TIMER16_0_IRQHandler(void)
|
||||
{
|
||||
/* Clear the interrupt flag */
|
||||
TMR_TMR16B0IR = TMR_TMR16B0IR_MR0;
|
||||
|
||||
/* Increment timer counter by 1 (it will automatically roll back to 0) */
|
||||
timer16_0_counter++;
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Interrupt handler for 16-bit timer 1
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void TIMER16_1_IRQHandler(void)
|
||||
{
|
||||
/* Clear the interrupt flag */
|
||||
TMR_TMR16B1IR = TMR_TMR16B1IR_MR0;
|
||||
|
||||
/* Increment timer counter by 1 (it will automatically roll back to 0) */
|
||||
timer16_1_counter++;
|
||||
|
||||
#ifdef CFG_PWM
|
||||
/* Check if the PWM output should be disabled after pwmMaxPulses pulses */
|
||||
/* See "drivers/pwm/pwm.c" */
|
||||
if (TMR_TMR16B1IR & TMR_TMR16B1IR_MR3)
|
||||
{
|
||||
/* Clear the interrupt flag */
|
||||
TMR_TMR16B1IR = TMR_TMR16B1IR_MR3;
|
||||
|
||||
if (pwmMaxPulses > 0)
|
||||
{
|
||||
pwmCounter++;
|
||||
if (pwmCounter == pwmMaxPulses)
|
||||
{
|
||||
/* Disable interrupt on MR3 */
|
||||
TMR_TMR16B1MCR &= ~(TMR_TMR16B1MCR_MR3_INT_MASK);
|
||||
/* Disable Timer */
|
||||
TMR_TMR16B1TCR &= ~(TMR_TMR16B1TCR_COUNTERENABLE_MASK);
|
||||
/* Reset the counter variables */
|
||||
pwmCounter = 0;
|
||||
pwmMaxPulses = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Enables the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to enable (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16Enable(uint8_t timerNum)
|
||||
{
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Disables the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to disable (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16Disable(uint8_t timerNum)
|
||||
{
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
TMR_TMR16B0TCR = TMR_TMR16B0TCR_COUNTERENABLE_DISABLED;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
TMR_TMR16B1TCR = TMR_TMR16B1TCR_COUNTERENABLE_DISABLED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Resets the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to reset (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16Reset(uint8_t timerNum)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
regVal = TMR_TMR16B0TCR;
|
||||
regVal |= TMR_TMR16B0TCR_COUNTERRESET_ENABLED;
|
||||
TMR_TMR16B0TCR = regVal;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
regVal = TMR_TMR16B1TCR;
|
||||
regVal |= TMR_TMR16B1TCR_COUNTERRESET_ENABLED;
|
||||
TMR_TMR16B1TCR = regVal;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the specified 16-bit timer, sets the timer
|
||||
interval, resets the timer, and configures the interrupt
|
||||
handler.
|
||||
|
||||
Initialises a 16-bit timer with the supplied timer interval (the
|
||||
amount of time that passes between each timer 'tick'). Every time that
|
||||
this interval elapses, the timer's interrupt will be fired and the
|
||||
appropriate counter variable will be incremented by one (For example,
|
||||
with CT16B0, 'timer16_0_counter' would be incremented).
|
||||
|
||||
@param[in] timerNum
|
||||
The 16-bit timer to initiliase (0..1)
|
||||
@param[in] timerInterval
|
||||
The number of clock 'ticks' between resets (0..65534)
|
||||
|
||||
@warning Care needs to be taken when configuring the timers since
|
||||
the pins are all multiplexed with other peripherals. This
|
||||
code is provided as a starting point, but it will need to
|
||||
be adjusted according to your own situation and
|
||||
pin/peripheral requirements
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer16Init(uint8_t timerNum, uint16_t timerInterval)
|
||||
{
|
||||
// If timerInterval is invalid, use the default value
|
||||
if (timerInterval < 1)
|
||||
{
|
||||
timerInterval = TIMER16_DEFAULTINTERVAL;
|
||||
}
|
||||
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
/* Enable the clock for CT16B0 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B0);
|
||||
|
||||
/* The physical pins associated with CT16B0 are not enabled by
|
||||
default in order to avoid conflicts with other peripherals.
|
||||
Pin 0.10 (CT16B0_MAT2), for example, can not be used while
|
||||
debugging with a hardware debugger. If you require one or
|
||||
more of these pins, simply uncomment the code below */
|
||||
|
||||
/* Configure PIO0.2 as Timer0_16 CAP0 */
|
||||
// IOCON_PIO0_2 &= ~IOCON_PIO0_2_FUNC_MASK;
|
||||
// IOCON_PIO0_2 |= IOCON_PIO0_2_FUNC_CT16B0_CAP0;
|
||||
|
||||
/* Configure PIO0.8 as Timer0_16 MAT0 */
|
||||
// IOCON_PIO0_8 &= ~IOCON_PIO0_8_FUNC_MASK;
|
||||
// IOCON_PIO0_8 |= IOCON_PIO0_8_FUNC_CT16B0_MAT0;
|
||||
|
||||
/* Configure PIO0.9 as Timer0_16 MAT1 */
|
||||
// IOCON_PIO0_9 &= ~IOCON_PIO0_9_FUNC_MASK;
|
||||
// IOCON_PIO0_9 |= IOCON_PIO0_9_FUNC_CT16B0_MAT1;
|
||||
|
||||
/* Configure PIO0.10 as Timer0_16 MAT3 */
|
||||
// IOCON_JTAG_TCK_PIO0_10 &= ~IOCON_JTAG_TCK_PIO0_10_FUNC_MASK;
|
||||
// IOCON_JTAG_TCK_PIO0_10 |= IOCON_JTAG_TCK_PIO0_10_FUNC_CT16B0_MAT2;
|
||||
|
||||
timer16_0_counter = 0;
|
||||
TMR_TMR16B0MR0 = timerInterval;
|
||||
|
||||
/* Configure match control register to raise an interrupt and reset on MR0 */
|
||||
TMR_TMR16B0MCR = (TMR_TMR16B0MCR_MR0_INT_ENABLED | TMR_TMR16B0MCR_MR0_RESET_ENABLED);
|
||||
|
||||
/* Enable the TIMER0 interrupt */
|
||||
NVIC_EnableIRQ(TIMER_16_0_IRQn);
|
||||
}
|
||||
|
||||
else if ( timerNum == 1 )
|
||||
{
|
||||
/* Enable the clock for CT16B1 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT16B1);
|
||||
|
||||
/* The physical pins associated with CT16B0 are not enabled by
|
||||
default in order to avoid conflicts with other peripherals.
|
||||
Pin 0.10 (CT16B0_MAT2), for example, can not be used while
|
||||
debugging with a hardware debugger. If you require one or
|
||||
more of these pins, simply uncomment the code below */
|
||||
|
||||
/* Configure PIO1.8 as Timer1_16 CAP0 */
|
||||
// IOCON_PIO1_8 &= ~IOCON_PIO1_8_FUNC_MASK;
|
||||
// IOCON_PIO1_8 |= IOCON_PIO1_8_FUNC_CT16B1_CAP0;
|
||||
|
||||
/* Configure PIO1.9 as Timer1_16 MAT0 */
|
||||
// IOCON_PIO1_9 &= ~IOCON_PIO1_9_FUNC_MASK;
|
||||
// IOCON_PIO1_9 |= IOCON_PIO1_9_FUNC_CT16B1_MAT0;
|
||||
|
||||
/* Configure PIO1.10 as Timer1_16 MAT1 */
|
||||
// IOCON_PIO1_10 &= ~IOCON_PIO1_10_FUNC_MASK;
|
||||
// IOCON_PIO1_10 |= IOCON_PIO1_10_FUNC_CT16B1_MAT1;
|
||||
|
||||
timer16_1_counter = 0;
|
||||
TMR_TMR16B1MR0 = timerInterval;
|
||||
|
||||
/* Configure match control register to raise an interrupt and reset on MR0 */
|
||||
TMR_TMR16B1MCR = (TMR_TMR16B1MCR_MR0_INT_ENABLED | TMR_TMR16B1MCR_MR0_RESET_ENABLED);
|
||||
|
||||
/* Enable the TIMER1 Interrupt */
|
||||
NVIC_EnableIRQ(TIMER_16_1_IRQn);
|
||||
}
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file timer16.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __TIMER16_H__
|
||||
#define __TIMER16_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#define TIMER16_DEFAULTINTERVAL (0xFFFF) // ~0.91mS @ 72MHz, ~1.37mS @ 48MHz
|
||||
|
||||
#define TIMER16_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000)
|
||||
#define TIMER16_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000)
|
||||
|
||||
void TIMER16_0_IRQHandler(void);
|
||||
void TIMER16_1_IRQHandler(void);
|
||||
|
||||
void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks);
|
||||
void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS);
|
||||
void timer16Enable(uint8_t timerNum);
|
||||
void timer16Disable(uint8_t timerNum);
|
||||
void timer16Reset(uint8_t timerNum);
|
||||
void timer16Init(uint8_t timerNum, uint16_t timerInterval);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,344 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file timer32.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Generic code for 32-bit timers. By default, the timers are configured
|
||||
to generate an interrupt once every 100 microseconds, incrementing a
|
||||
global variable once per tick.
|
||||
|
||||
@warning Please note that the ROM-based USB drivers on the LPC1343
|
||||
require the use of 32-bit Timer 1. If you plan on using the
|
||||
ROM-based USB functionality, you should restrict your timer
|
||||
usage to 32-bit timer 0.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
#include "/core/cpu/cpu.h"
|
||||
#include "/core/timer32/timer32.h"
|
||||
...
|
||||
cpuInit();
|
||||
|
||||
// Initialise 32-bit timer 0 with 100uS ticks
|
||||
timer32Init(0, TIMER32_DEFAULTINTERVAL);
|
||||
|
||||
// Enable timer 0
|
||||
timer32Enable(0);
|
||||
|
||||
// Cause a blocking delay for 1 second (1000mS)
|
||||
timer32Delay(0, TIMER32_DELAY_1MS * 1000);
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "timer32.h"
|
||||
|
||||
volatile uint32_t timer32_0_counter = 0;
|
||||
volatile uint32_t timer32_1_counter = 0;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Causes a blocking delay for the specified number of
|
||||
timer ticks. The duration of each 'tick' is determined by
|
||||
the 'timerInterval' property supplied to timer32Init.
|
||||
|
||||
@param[in] timerNum
|
||||
The 32-bit timer to user (0..1)
|
||||
@param[in] delay
|
||||
The number of counter increments to wait
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer32Delay(uint8_t timerNum, uint32_t delay)
|
||||
{
|
||||
uint32_t curTicks;
|
||||
|
||||
if (timerNum == 0)
|
||||
{
|
||||
curTicks = timer32_0_counter;
|
||||
if (curTicks > 0xFFFFFFFF - delay)
|
||||
{
|
||||
// Rollover will occur during delay
|
||||
while (timer32_0_counter >= curTicks)
|
||||
{
|
||||
while (timer32_0_counter < (delay - (0xFFFFFFFF - curTicks)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((timer32_0_counter - curTicks) < delay);
|
||||
}
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
curTicks = timer32_1_counter;
|
||||
if (curTicks > 0xFFFFFFFF - delay)
|
||||
{
|
||||
// Rollover will occur during delay
|
||||
while (timer32_1_counter >= curTicks)
|
||||
{
|
||||
while (timer32_1_counter < (delay - (0xFFFFFFFF - curTicks)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((timer32_1_counter - curTicks) < delay);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Interrupt handler for 32-bit timer 0
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void TIMER32_0_IRQHandler(void)
|
||||
{
|
||||
/* Clear the interrupt flag */
|
||||
TMR_TMR32B0IR = TMR_TMR32B0IR_MR0;
|
||||
|
||||
/* If you wish to perform some action after each timer 'tick' (such as
|
||||
incrementing a counter variable) you can do so here */
|
||||
timer32_0_counter++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Interrupt handler for 32-bit timer 1
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void TIMER32_1_IRQHandler(void)
|
||||
{
|
||||
/* Clear the interrupt flag */
|
||||
TMR_TMR32B1IR = TMR_TMR32B1IR_MR0;
|
||||
|
||||
/* If you wish to perform some action after each timer 'tick' (such as
|
||||
incrementing a counter variable) you can do so here */
|
||||
timer32_1_counter++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Enables the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 32-bit timer to enable (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer32Enable(uint8_t timerNum)
|
||||
{
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_ENABLED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Disables the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 32-bit timer to disable (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer32Disable(uint8_t timerNum)
|
||||
{
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
TMR_TMR32B1TCR = TMR_TMR32B1TCR_COUNTERENABLE_DISABLED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Resets the specified timer
|
||||
|
||||
@param[in] timerNum
|
||||
The 32-bit timer to reset (0..1)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer32Reset(uint8_t timerNum)
|
||||
{
|
||||
uint32_t regVal;
|
||||
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
regVal = TMR_TMR32B0TCR;
|
||||
regVal |= TMR_TMR32B0TCR_COUNTERRESET_ENABLED;
|
||||
TMR_TMR32B0TCR = regVal;
|
||||
}
|
||||
|
||||
else if (timerNum == 1)
|
||||
{
|
||||
regVal = TMR_TMR32B1TCR;
|
||||
regVal |= TMR_TMR32B1TCR_COUNTERRESET_ENABLED;
|
||||
TMR_TMR32B1TCR = regVal;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the specified 32-bit timer, and configures the
|
||||
timer to raise an interrupt and reset on match on MR0.
|
||||
|
||||
@param[in] timerNum
|
||||
The 32-bit timer to initiliase (0..1)
|
||||
@param[in] timerInterval
|
||||
The number of clock 'ticks' between resets (0..0xFFFFFFFF)
|
||||
|
||||
@note Care needs to be taken when configuring the timers since the
|
||||
pins are all multiplexed with other peripherals. This code is
|
||||
provided as a starting point, but it will need to be adjusted
|
||||
according to your own situation and pin/peripheral requirements
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void timer32Init(uint8_t timerNum, uint32_t timerInterval)
|
||||
{
|
||||
// If timerInterval is invalid, use the default value
|
||||
if (timerInterval < 1)
|
||||
{
|
||||
timerInterval = TIMER32_DEFAULTINTERVAL;
|
||||
}
|
||||
|
||||
if ( timerNum == 0 )
|
||||
{
|
||||
/* Enable the clock for CT32B0 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
|
||||
|
||||
/* The physical pins associated with CT32B0 are not enabled by
|
||||
default in order to avoid conflicts with other peripherals. If
|
||||
you wish to use any of the pin-dependant functionality, simply
|
||||
uncomment the appropriate lines below. */
|
||||
|
||||
/* Configure PIO1.5 as Timer0_32 CAP0 */
|
||||
// IOCON_PIO1_5 &= ~IOCON_PIO1_5_FUNC_MASK;
|
||||
// IOCON_PIO1_5 |= IOCON_PIO1_5_FUNC_CT32B0_CAP0;
|
||||
|
||||
/* Configure PIO1.6 as Timer0_32 MAT0 */
|
||||
// IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK;
|
||||
// IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_CT32B0_MAT0;
|
||||
|
||||
/* Configure PIO1.7 as Timer0_32 MAT1 */
|
||||
// IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK;
|
||||
// IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_CT32B0_MAT1;
|
||||
|
||||
/* Configure PIO0.1 as Timer0_32 MAT2 */
|
||||
// IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK;
|
||||
// IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CT32B0_MAT2;
|
||||
|
||||
/* Configure PIO0.11 as Timer0_32 MAT3 */
|
||||
/* Note: This pint can not be used with JTAG/SWD */
|
||||
// IOCON_JTAG_TDI_PIO0_11 &= ~IOCON_JTAG_TDI_PIO0_11_FUNC_MASK;
|
||||
// IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_CT32B0_MAT3;
|
||||
|
||||
timer32_0_counter = 0;
|
||||
TMR_TMR32B0MR0 = timerInterval;
|
||||
|
||||
/* Configure match control register to raise an interrupt and reset on MR0 */
|
||||
TMR_TMR32B0MCR = (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED);
|
||||
|
||||
/* Enable the TIMER0 interrupt */
|
||||
NVIC_EnableIRQ(TIMER_32_0_IRQn);
|
||||
}
|
||||
|
||||
else if ( timerNum == 1 )
|
||||
{
|
||||
/* Enable the clock for CT32B1 */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1);
|
||||
|
||||
/* The physical pins associated with CT32B0 are not enabled by
|
||||
default in order to avoid conflicts with other peripherals. */
|
||||
|
||||
/* Configure PIO1.0 as Timer1_32 CAP0 */
|
||||
/* Note: This pint can not be used with JTAG/SWD */
|
||||
// IOCON_JTAG_TMS_PIO1_0 &= ~IOCON_JTAG_TMS_PIO1_0_FUNC_MASK;
|
||||
// IOCON_JTAG_TMS_PIO1_0 |= IOCON_JTAG_TMS_PIO1_0_FUNC_CT32B1_CAP0;
|
||||
|
||||
/* Configure PIO1.1 as Timer1_32 MAT0 */
|
||||
/* Note: This pint can not be used with JTAG/SWD */
|
||||
// IOCON_JTAG_TDO_PIO1_1 &= ~IOCON_JTAG_TDO_PIO1_1_FUNC_MASK;
|
||||
// IOCON_JTAG_TDO_PIO1_1 |= IOCON_JTAG_TDO_PIO1_1_FUNC_CT32B1_MAT0;
|
||||
|
||||
/* Configure PIO1.2 as Timer1_32 MAT1 */
|
||||
/* Note: This pint can not be used with JTAG/SWD */
|
||||
// IOCON_JTAG_nTRST_PIO1_2 &= ~IOCON_JTAG_nTRST_PIO1_2_FUNC_MASK;
|
||||
// IOCON_JTAG_nTRST_PIO1_2 |= IOCON_JTAG_nTRST_PIO1_2_FUNC_CT32B1_MAT1;
|
||||
|
||||
/* Configure PIO1.3 as Timer1_32 MAT2 */
|
||||
/* Note: This pint can not be used with JTAG/SWD */
|
||||
// IOCON_SWDIO_PIO1_3 &= ~IOCON_SWDIO_PIO1_3_FUNC_MASK;
|
||||
// IOCON_SWDIO_PIO1_3 |= IOCON_SWDIO_PIO1_3_FUNC_CT32B1_MAT2;
|
||||
|
||||
/* Configure PIO1.4 as Timer1_32 MAT3 */
|
||||
// IOCON_PIO1_4 &= ~IOCON_PIO1_4_FUNC_MASK;
|
||||
// IOCON_PIO1_4 |= IOCON_PIO1_4_FUNC_CT32B1_MAT3;
|
||||
|
||||
timer32_1_counter = 0;
|
||||
TMR_TMR32B1MR0 = timerInterval;
|
||||
|
||||
/* Configure match control register to raise an interrupt and reset on MR0 */
|
||||
TMR_TMR32B1MCR = (TMR_TMR32B1MCR_MR0_INT_ENABLED | TMR_TMR32B1MCR_MR0_RESET_ENABLED);
|
||||
|
||||
/* Enable the TIMER1 Interrupt */
|
||||
NVIC_EnableIRQ(TIMER_32_1_IRQn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file timer32.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __TIMER32_H__
|
||||
#define __TIMER32_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#define TIMER32_CCLK_1US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000000)
|
||||
#define TIMER32_CCLK_10US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100000)
|
||||
#define TIMER32_CCLK_100US ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10000)
|
||||
#define TIMER32_CCLK_1MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 1000)
|
||||
#define TIMER32_CCLK_10MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 100)
|
||||
#define TIMER32_CCLK_100MS ((CFG_CPU_CCLK/SCB_SYSAHBCLKDIV) / 10)
|
||||
#define TIMER32_CCLK_1S (CFG_CPU_CCLK/SCB_SYSAHBCLKDIV)
|
||||
#define TIMER32_DEFAULTINTERVAL (TIMER32_CCLK_100US)
|
||||
|
||||
#define TIMER32_DELAY_100US (1) // 100uS delay = 1 tick
|
||||
#define TIMER32_DELAY_1MS (10) // 1mS delay = 10 ticks
|
||||
#define TIMER32_DELAY_1S (10000) // 1S delay = 10000 ticks
|
||||
|
||||
void TIMER32_0_IRQHandler(void);
|
||||
void TIMER32_1_IRQHandler(void);
|
||||
|
||||
void timer32Delay(uint8_t timerNum, uint32_t delay);
|
||||
void timer32Enable(uint8_t timerNum);
|
||||
void timer32Disable(uint8_t timerNum);
|
||||
void timer32Reset(uint8_t timerNum);
|
||||
void timer32Init(uint8_t timerNum, uint32_t timerInterval);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,347 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file uart.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Generic code for UART-based communication. Incoming text is stored
|
||||
in a FIFO Queue for safer processing.
|
||||
|
||||
@section Example: Sending text via UART
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/uart/uart.h"
|
||||
...
|
||||
#define UARTBUFFERSIZE 5
|
||||
...
|
||||
cpuInit();
|
||||
uartInit(57600);
|
||||
...
|
||||
uint8_t uartBuffer[UARTBUFFERSIZE] = { 'T', 'e', 's', 't', '\n' };
|
||||
|
||||
// Send contents of uartBuffer
|
||||
uartSend((uint8_t *)uartBuffer, UARTBUFFERSIZE);
|
||||
@endcode
|
||||
|
||||
@section Example: Reading from UART
|
||||
|
||||
@code
|
||||
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/uart/uart.h"
|
||||
|
||||
cpuInit();
|
||||
uartInit(57600);
|
||||
|
||||
// Get a reference to the UART control block
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
|
||||
// Read any text available in the queue
|
||||
while (uartRxBufferDataPending())
|
||||
{
|
||||
// Read the first available character
|
||||
uint8_t c = uartRxBufferRead();
|
||||
|
||||
// read out the data in the buffer and echo it back to the host.
|
||||
switch (c)
|
||||
{
|
||||
case '\r':
|
||||
printf("\n\r");
|
||||
break;
|
||||
default:
|
||||
printf("%c", c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#ifdef CFG_INTERFACE_UART
|
||||
#include "core/cmd/cmd.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
UART protocol control block, which is used to safely access the
|
||||
RX FIFO buffer from elsewhere in the code. This should be accessed
|
||||
through 'uartGetPCB()'.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static uart_pcb_t pcb;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
IRQ to handle incoming data, etc.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void UART_IRQHandler(void)
|
||||
{
|
||||
uint8_t IIRValue, LSRValue;
|
||||
uint8_t Dummy = Dummy;
|
||||
|
||||
IIRValue = UART_U0IIR;
|
||||
IIRValue &= ~(UART_U0IIR_IntStatus_MASK); /* skip pending bit in IIR */
|
||||
IIRValue &= UART_U0IIR_IntId_MASK; /* check bit 1~3, interrupt identification */
|
||||
|
||||
// 1.) Check receiver line status
|
||||
if (IIRValue == UART_U0IIR_IntId_RLS)
|
||||
{
|
||||
LSRValue = UART_U0LSR;
|
||||
// Check for errors
|
||||
if (LSRValue & (UART_U0LSR_OE | UART_U0LSR_PE | UART_U0LSR_FE | UART_U0LSR_RXFE | UART_U0LSR_BI))
|
||||
{
|
||||
/* There are errors or break interrupt */
|
||||
/* Read LSR will clear the interrupt */
|
||||
pcb.status = LSRValue;
|
||||
Dummy = UART_U0RBR; /* Dummy read on RX to clear interrupt, then bail out */
|
||||
return;
|
||||
}
|
||||
// No error and receive data is ready
|
||||
if (LSRValue & UART_U0LSR_RDR_DATA)
|
||||
{
|
||||
/* If no error on RLS, normal ready, save into the data buffer. */
|
||||
/* Note: read RBR will clear the interrupt */
|
||||
uartRxBufferWrite(UART_U0RBR);
|
||||
}
|
||||
}
|
||||
|
||||
// 2.) Check receive data available
|
||||
else if (IIRValue == UART_U0IIR_IntId_RDA)
|
||||
{
|
||||
// Add incoming text to UART buffer
|
||||
uartRxBufferWrite(UART_U0RBR);
|
||||
}
|
||||
|
||||
// 3.) Check character timeout indicator
|
||||
else if (IIRValue == UART_U0IIR_IntId_CTI)
|
||||
{
|
||||
/* Bit 9 as the CTI error */
|
||||
pcb.status |= 0x100;
|
||||
}
|
||||
|
||||
// 4.) Check THRE (transmit holding register empty)
|
||||
else if (IIRValue == UART_U0IIR_IntId_THRE)
|
||||
{
|
||||
/* Check status in the LSR to see if valid data in U0THR or not */
|
||||
LSRValue = UART_U0LSR;
|
||||
if (LSRValue & UART_U0LSR_THRE)
|
||||
{
|
||||
pcb.pending_tx_data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcb.pending_tx_data= 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Get a pointer to the UART's protocol control block, which can
|
||||
be used to control the RX FIFO buffer and check whether UART
|
||||
has already been initialised or not.
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Make sure that UART is initialised
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
if (!pcb->initialised)
|
||||
{
|
||||
uartInit(CFG_UART_BAUDRATE);
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uart_pcb_t *uartGetPCB()
|
||||
{
|
||||
return &pcb;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises UART at the specified baud rate.
|
||||
|
||||
@param[in] baudRate
|
||||
The baud rate to use when configuring the UART.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartInit(uint32_t baudrate)
|
||||
{
|
||||
uint32_t fDiv;
|
||||
uint32_t regVal;
|
||||
|
||||
NVIC_DisableIRQ(UART_IRQn);
|
||||
|
||||
// Clear protocol control blocks
|
||||
memset(&pcb, 0, sizeof(uart_pcb_t));
|
||||
pcb.pending_tx_data = 0;
|
||||
uartRxBufferInit();
|
||||
|
||||
/* Set 1.6 UART RXD */
|
||||
IOCON_PIO1_6 &= ~IOCON_PIO1_6_FUNC_MASK;
|
||||
IOCON_PIO1_6 |= IOCON_PIO1_6_FUNC_UART_RXD;
|
||||
|
||||
/* Set 1.7 UART TXD */
|
||||
IOCON_PIO1_7 &= ~IOCON_PIO1_7_FUNC_MASK;
|
||||
IOCON_PIO1_7 |= IOCON_PIO1_7_FUNC_UART_TXD;
|
||||
|
||||
/* Enable UART clock */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_UART);
|
||||
SCB_UARTCLKDIV = SCB_UARTCLKDIV_DIV1; /* divided by 1 */
|
||||
|
||||
/* 8 bits, no Parity, 1 Stop bit */
|
||||
UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars |
|
||||
UART_U0LCR_Stop_Bit_Select_1Bits |
|
||||
UART_U0LCR_Parity_Disabled |
|
||||
UART_U0LCR_Parity_Select_OddParity |
|
||||
UART_U0LCR_Break_Control_Disabled |
|
||||
UART_U0LCR_Divisor_Latch_Access_Enabled);
|
||||
|
||||
/* Baud rate */
|
||||
regVal = SCB_UARTCLKDIV;
|
||||
fDiv = (((CFG_CPU_CCLK * SCB_SYSAHBCLKDIV)/regVal)/16)/baudrate;
|
||||
|
||||
UART_U0DLM = fDiv / 256;
|
||||
UART_U0DLL = fDiv % 256;
|
||||
|
||||
/* Set DLAB back to 0 */
|
||||
UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars |
|
||||
UART_U0LCR_Stop_Bit_Select_1Bits |
|
||||
UART_U0LCR_Parity_Disabled |
|
||||
UART_U0LCR_Parity_Select_OddParity |
|
||||
UART_U0LCR_Break_Control_Disabled |
|
||||
UART_U0LCR_Divisor_Latch_Access_Disabled);
|
||||
|
||||
/* Enable and reset TX and RX FIFO. */
|
||||
UART_U0FCR = (UART_U0FCR_FIFO_Enabled |
|
||||
UART_U0FCR_Rx_FIFO_Reset |
|
||||
UART_U0FCR_Tx_FIFO_Reset);
|
||||
|
||||
/* Read to clear the line status. */
|
||||
regVal = UART_U0LSR;
|
||||
|
||||
/* Ensure a clean start, no data in either TX or RX FIFO. */
|
||||
while (( UART_U0LSR & (UART_U0LSR_THRE|UART_U0LSR_TEMT)) != (UART_U0LSR_THRE|UART_U0LSR_TEMT) );
|
||||
while ( UART_U0LSR & UART_U0LSR_RDR_DATA )
|
||||
{
|
||||
/* Dump data from RX FIFO */
|
||||
regVal = UART_U0RBR;
|
||||
}
|
||||
|
||||
/* Set the initialised flag in the protocol control block */
|
||||
pcb.initialised = 1;
|
||||
pcb.baudrate = baudrate;
|
||||
|
||||
/* Enable the UART Interrupt */
|
||||
NVIC_EnableIRQ(UART_IRQn);
|
||||
UART_U0IER = UART_U0IER_RBR_Interrupt_Enabled | UART_U0IER_RLS_Interrupt_Enabled;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends the contents of supplied text buffer over UART.
|
||||
|
||||
@param[in] bufferPtr
|
||||
Pointer to the text buffer
|
||||
@param[in] bufferPtr
|
||||
The size of the text buffer
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Set 5-character text buffer
|
||||
uint8_t uartBuffer[5] = { 'T', 'e', 's', 't', '\n' };
|
||||
// Send contents of uartBuffer
|
||||
uartSend((uint8_t *)uartBuffer, 5);
|
||||
@endcode
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartSend (uint8_t *bufferPtr, uint32_t length)
|
||||
{
|
||||
while (length != 0)
|
||||
{
|
||||
/* THRE status, contain valid data */
|
||||
while ( !(UART_U0LSR & UART_U0LSR_THRE) );
|
||||
UART_U0THR = *bufferPtr;
|
||||
|
||||
bufferPtr++;
|
||||
length--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sends a single byte over UART.
|
||||
|
||||
@param[in] byte
|
||||
Byte value to send
|
||||
|
||||
@section Example
|
||||
|
||||
@code
|
||||
// Send 0xFF over UART
|
||||
uartSendByte(0xFF);
|
||||
// Send 'B' over UART (note single quotes)
|
||||
uartSendByte('B');
|
||||
@endcode
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartSendByte (uint8_t byte)
|
||||
{
|
||||
/* THRE status, contain valid data */
|
||||
while ( !(UART_U0LSR & UART_U0LSR_THRE) );
|
||||
UART_U0THR = byte;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file uart.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef __UART_H__
|
||||
#define __UART_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
// Buffer used for circular fifo
|
||||
typedef struct _uart_buffer_t
|
||||
{
|
||||
uint8_t ep_dir;
|
||||
volatile uint8_t len;
|
||||
volatile uint8_t wr_ptr;
|
||||
volatile uint8_t rd_ptr;
|
||||
uint8_t buf[CFG_UART_BUFSIZE];
|
||||
} uart_buffer_t;
|
||||
|
||||
// UART Protocol control block
|
||||
typedef struct _uart_pcb_t
|
||||
{
|
||||
BOOL initialised;
|
||||
uint32_t baudrate;
|
||||
uint32_t status;
|
||||
uint32_t pending_tx_data;
|
||||
uart_buffer_t rxfifo;
|
||||
} uart_pcb_t;
|
||||
|
||||
void UART_IRQHandler(void);
|
||||
uart_pcb_t *uartGetPCB();
|
||||
void uartInit(uint32_t Baudrate);
|
||||
void uartSend(uint8_t *BufferPtr, uint32_t Length);
|
||||
void uartSendByte (uint8_t byte);
|
||||
|
||||
// Rx Buffer access control
|
||||
void uartRxBufferInit();
|
||||
uint8_t uartRxBufferRead();
|
||||
void uartRxBufferWrite(uint8_t data);
|
||||
void uartRxBufferClearFIFO();
|
||||
uint8_t uartRxBufferDataPending();
|
||||
bool uartRxBufferReadArray(byte_t* rx, size_t* len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,149 @@
|
|||
/*******************************************************************
|
||||
Copyright (C) 2009 FreakLabs
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Originally written by Christopher Wang aka Akiba.
|
||||
Please post support questions to the FreakLabs forum.
|
||||
*******************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file uart_buf.c
|
||||
@author Christopher Wang (Freaklabs)
|
||||
Modified by: K. Townsend (microBuilder.eu)
|
||||
@date 19 May 2010
|
||||
|
||||
Original code taken from the FreakUSB Open Source USB Device Stack
|
||||
http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
|
||||
|
||||
If it works well, you can thank Akiba at Freaklabs. If it fails
|
||||
miserably, you can blame me (since parts of it it were rather
|
||||
ungraciously modified). :-)
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initialises the RX FIFO buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartRxBufferInit()
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
pcb->rxfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Read one byte out of the RX buffer. This function will return the byte
|
||||
located at the array index of the read pointer, and then increment the
|
||||
read pointer index. If the read pointer exceeds the maximum buffer
|
||||
size, it will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t uartRxBufferRead()
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
uint8_t data;
|
||||
|
||||
data = pcb->rxfifo.buf[pcb->rxfifo.rd_ptr];
|
||||
pcb->rxfifo.rd_ptr = (pcb->rxfifo.rd_ptr + 1) % CFG_UART_BUFSIZE;
|
||||
pcb->rxfifo.len--;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Read byte array from uart
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool uartRxBufferReadArray(byte_t* rx, size_t* len)
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
*len = 0;
|
||||
|
||||
while(pcb->rxfifo.len != 0)
|
||||
{
|
||||
(*rx) = uartRxBufferRead();
|
||||
(*len)++;
|
||||
rx++;
|
||||
}
|
||||
|
||||
return (*len != 0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Write one byte into the RX buffer. This function will write one
|
||||
byte into the array index specified by the write pointer and increment
|
||||
the write index. If the write index exceeds the max buffer size, then it
|
||||
will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartRxBufferWrite(uint8_t data)
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
|
||||
pcb->rxfifo.buf[pcb->rxfifo.wr_ptr] = data;
|
||||
pcb->rxfifo.wr_ptr = (pcb->rxfifo.wr_ptr + 1) % CFG_UART_BUFSIZE;
|
||||
pcb->rxfifo.len++;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Clear the fifo read and write pointers and set the length to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void uartRxBufferClearFIFO()
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
|
||||
pcb->rxfifo.rd_ptr = 0;
|
||||
pcb->rxfifo.wr_ptr = 0;
|
||||
pcb->rxfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Check whether there is any data pending on the RX buffer.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t uartRxBufferDataPending()
|
||||
{
|
||||
uart_pcb_t *pcb = uartGetPCB();
|
||||
|
||||
if (pcb->rxfifo.len != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: CDC.h
|
||||
* Purpose: USB Communication Device Class Definitions
|
||||
* Version: V1.00
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CDC_H
|
||||
#define __CDC_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions based on usbcdc11.pdf (www.usb.org)
|
||||
*---------------------------------------------------------------------------*/
|
||||
// Communication device class specification version 1.10
|
||||
#define CDC_V1_10 0x0110
|
||||
|
||||
// Communication interface class code
|
||||
// (usbcdc11.pdf, 4.2, Table 15)
|
||||
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
|
||||
|
||||
// Communication interface class subclass codes
|
||||
// (usbcdc11.pdf, 4.3, Table 16)
|
||||
#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01
|
||||
#define CDC_ABSTRACT_CONTROL_MODEL 0x02
|
||||
#define CDC_TELEPHONE_CONTROL_MODEL 0x03
|
||||
#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04
|
||||
#define CDC_CAPI_CONTROL_MODEL 0x05
|
||||
#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06
|
||||
#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07
|
||||
|
||||
// Communication interface class control protocol codes
|
||||
// (usbcdc11.pdf, 4.4, Table 17)
|
||||
#define CDC_PROTOCOL_COMMON_AT_COMMANDS 0x01
|
||||
|
||||
// Data interface class code
|
||||
// (usbcdc11.pdf, 4.5, Table 18)
|
||||
#define CDC_DATA_INTERFACE_CLASS 0x0A
|
||||
|
||||
// Data interface class protocol codes
|
||||
// (usbcdc11.pdf, 4.7, Table 19)
|
||||
#define CDC_PROTOCOL_ISDN_BRI 0x30
|
||||
#define CDC_PROTOCOL_HDLC 0x31
|
||||
#define CDC_PROTOCOL_TRANSPARENT 0x32
|
||||
#define CDC_PROTOCOL_Q921_MANAGEMENT 0x50
|
||||
#define CDC_PROTOCOL_Q921_DATA_LINK 0x51
|
||||
#define CDC_PROTOCOL_Q921_MULTIPLEXOR 0x52
|
||||
#define CDC_PROTOCOL_V42 0x90
|
||||
#define CDC_PROTOCOL_EURO_ISDN 0x91
|
||||
#define CDC_PROTOCOL_V24_RATE_ADAPTATION 0x92
|
||||
#define CDC_PROTOCOL_CAPI 0x93
|
||||
#define CDC_PROTOCOL_HOST_BASED_DRIVER 0xFD
|
||||
#define CDC_PROTOCOL_DESCRIBED_IN_PUFD 0xFE
|
||||
|
||||
// Type values for bDescriptorType field of functional descriptors
|
||||
// (usbcdc11.pdf, 5.2.3, Table 24)
|
||||
#define CDC_CS_INTERFACE 0x24
|
||||
#define CDC_CS_ENDPOINT 0x25
|
||||
|
||||
// Type values for bDescriptorSubtype field of functional descriptors
|
||||
// (usbcdc11.pdf, 5.2.3, Table 25)
|
||||
#define CDC_HEADER 0x00
|
||||
#define CDC_CALL_MANAGEMENT 0x01
|
||||
#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
|
||||
#define CDC_DIRECT_LINE_MANAGEMENT 0x03
|
||||
#define CDC_TELEPHONE_RINGER 0x04
|
||||
#define CDC_REPORTING_CAPABILITIES 0x05
|
||||
#define CDC_UNION 0x06
|
||||
#define CDC_COUNTRY_SELECTION 0x07
|
||||
#define CDC_TELEPHONE_OPERATIONAL_MODES 0x08
|
||||
#define CDC_USB_TERMINAL 0x09
|
||||
#define CDC_NETWORK_CHANNEL 0x0A
|
||||
#define CDC_PROTOCOL_UNIT 0x0B
|
||||
#define CDC_EXTENSION_UNIT 0x0C
|
||||
#define CDC_MULTI_CHANNEL_MANAGEMENT 0x0D
|
||||
#define CDC_CAPI_CONTROL_MANAGEMENT 0x0E
|
||||
#define CDC_ETHERNET_NETWORKING 0x0F
|
||||
#define CDC_ATM_NETWORKING 0x10
|
||||
|
||||
// CDC class-specific request codes
|
||||
// (usbcdc11.pdf, 6.2, Table 46)
|
||||
// see Table 45 for info about the specific requests.
|
||||
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
|
||||
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
|
||||
#define CDC_SET_COMM_FEATURE 0x02
|
||||
#define CDC_GET_COMM_FEATURE 0x03
|
||||
#define CDC_CLEAR_COMM_FEATURE 0x04
|
||||
#define CDC_SET_AUX_LINE_STATE 0x10
|
||||
#define CDC_SET_HOOK_STATE 0x11
|
||||
#define CDC_PULSE_SETUP 0x12
|
||||
#define CDC_SEND_PULSE 0x13
|
||||
#define CDC_SET_PULSE_TIME 0x14
|
||||
#define CDC_RING_AUX_JACK 0x15
|
||||
#define CDC_SET_LINE_CODING 0x20
|
||||
#define CDC_GET_LINE_CODING 0x21
|
||||
#define CDC_SET_CONTROL_LINE_STATE 0x22
|
||||
#define CDC_SEND_BREAK 0x23
|
||||
#define CDC_SET_RINGER_PARMS 0x30
|
||||
#define CDC_GET_RINGER_PARMS 0x31
|
||||
#define CDC_SET_OPERATION_PARMS 0x32
|
||||
#define CDC_GET_OPERATION_PARMS 0x33
|
||||
#define CDC_SET_LINE_PARMS 0x34
|
||||
#define CDC_GET_LINE_PARMS 0x35
|
||||
#define CDC_DIAL_DIGITS 0x36
|
||||
#define CDC_SET_UNIT_PARAMETER 0x37
|
||||
#define CDC_GET_UNIT_PARAMETER 0x38
|
||||
#define CDC_CLEAR_UNIT_PARAMETER 0x39
|
||||
#define CDC_GET_PROFILE 0x3A
|
||||
#define CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
|
||||
#define CDC_SET_ETHERNET_PMP_FILTER 0x41
|
||||
#define CDC_GET_ETHERNET_PMP_FILTER 0x42
|
||||
#define CDC_SET_ETHERNET_PACKET_FILTER 0x43
|
||||
#define CDC_GET_ETHERNET_STATISTIC 0x44
|
||||
#define CDC_SET_ATM_DATA_FORMAT 0x50
|
||||
#define CDC_GET_ATM_DEVICE_STATISTICS 0x51
|
||||
#define CDC_SET_ATM_DEFAULT_VC 0x52
|
||||
#define CDC_GET_ATM_VC_STATISTICS 0x53
|
||||
|
||||
// Communication feature selector codes
|
||||
// (usbcdc11.pdf, 6.2.2..6.2.4, Table 47)
|
||||
#define CDC_ABSTRACT_STATE 0x01
|
||||
#define CDC_COUNTRY_SETTING 0x02
|
||||
|
||||
// Feature Status returned for ABSTRACT_STATE Selector
|
||||
// (usbcdc11.pdf, 6.2.3, Table 48)
|
||||
#define CDC_IDLE_SETTING (1 << 0)
|
||||
#define CDC_DATA_MULTPLEXED_STATE (1 << 1)
|
||||
|
||||
|
||||
// Control signal bitmap values for the SetControlLineState request
|
||||
// (usbcdc11.pdf, 6.2.14, Table 51)
|
||||
#define CDC_DTE_PRESENT (1 << 0)
|
||||
#define CDC_ACTIVATE_CARRIER (1 << 1)
|
||||
|
||||
// CDC class-specific notification codes
|
||||
// (usbcdc11.pdf, 6.3, Table 68)
|
||||
// see Table 67 for Info about class-specific notifications
|
||||
#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00
|
||||
#define CDC_RESPONSE_AVAILABLE 0x01
|
||||
#define CDC_AUX_JACK_HOOK_STATE 0x08
|
||||
#define CDC_RING_DETECT 0x09
|
||||
#define CDC_NOTIFICATION_SERIAL_STATE 0x20
|
||||
#define CDC_CALL_STATE_CHANGE 0x28
|
||||
#define CDC_LINE_STATE_CHANGE 0x29
|
||||
#define CDC_CONNECTION_SPEED_CHANGE 0x2A
|
||||
|
||||
// UART state bitmap values (Serial state notification).
|
||||
// (usbcdc11.pdf, 6.3.5, Table 69)
|
||||
#define CDC_SERIAL_STATE_OVERRUN (1 << 6) // receive data overrun error has occurred
|
||||
#define CDC_SERIAL_STATE_PARITY (1 << 5) // parity error has occurred
|
||||
#define CDC_SERIAL_STATE_FRAMING (1 << 4) // framing error has occurred
|
||||
#define CDC_SERIAL_STATE_RING (1 << 3) // state of ring signal detection
|
||||
#define CDC_SERIAL_STATE_BREAK (1 << 2) // state of break detection
|
||||
#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) // state of transmission carrier
|
||||
#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) // state of receiver carrier
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Structures based on usbcdc11.pdf (www.usb.org)
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
// Header functional descriptor
|
||||
// (usbcdc11.pdf, 5.2.3.1)
|
||||
// This header must precede any list of class-specific descriptors.
|
||||
typedef struct _CDC_HEADER_DESCRIPTOR{
|
||||
uint8_t bFunctionLength; // size of this descriptor in bytes
|
||||
uint8_t bDescriptorType; // CS_INTERFACE descriptor type
|
||||
uint8_t bDescriptorSubtype; // Header functional descriptor subtype
|
||||
uint16_t bcdCDC; // USB CDC specification release version
|
||||
} __attribute__((packed)) CDC_HEADER_DESCRIPTOR;
|
||||
|
||||
//Call management functional descriptor
|
||||
// (usbcdc11.pdf, 5.2.3.2)
|
||||
// Describes the processing of calls for the communication class interface.
|
||||
typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR {
|
||||
uint8_t bFunctionLength; // size of this descriptor in bytes
|
||||
uint8_t bDescriptorType; // CS_INTERFACE descriptor type
|
||||
uint8_t bDescriptorSubtype; // call management functional descriptor subtype
|
||||
uint8_t bmCapabilities; // capabilities that this configuration supports
|
||||
uint8_t bDataInterface; // interface number of the data class interface used for call management (optional)
|
||||
} __attribute__((packed)) CDC_CALL_MANAGEMENT_DESCRIPTOR;
|
||||
|
||||
// Abstract control management functional descriptor
|
||||
// (usbcdc11.pdf, 5.2.3.3)
|
||||
// Describes the command supported by the communication interface class with the Abstract Control Model subclass code.
|
||||
typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR {
|
||||
uint8_t bFunctionLength; // size of this descriptor in bytes
|
||||
uint8_t bDescriptorType; // CS_INTERFACE descriptor type
|
||||
uint8_t bDescriptorSubtype; // abstract control management functional descriptor subtype
|
||||
uint8_t bmCapabilities; // capabilities supported by this configuration
|
||||
} __attribute__((packed)) CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR;
|
||||
|
||||
// Union functional descriptors
|
||||
// (usbcdc11.pdf, 5.2.3.8)
|
||||
// Describes the relationship between a group of interfaces that can be considered to form a functional unit.
|
||||
typedef struct _CDC_UNION_DESCRIPTOR {
|
||||
uint8_t bFunctionLength; // size of this descriptor in bytes
|
||||
uint8_t bDescriptorType; // CS_INTERFACE descriptor type
|
||||
uint8_t bDescriptorSubtype; // union functional descriptor subtype
|
||||
uint8_t bMasterInterface; // interface number designated as master
|
||||
} __attribute__((packed)) CDC_UNION_DESCRIPTOR;
|
||||
|
||||
// Union functional descriptors with one slave interface
|
||||
// (usbcdc11.pdf, 5.2.3.8)
|
||||
typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR {
|
||||
CDC_UNION_DESCRIPTOR sUnion; // Union functional descriptor
|
||||
uint8_t bSlaveInterfaces[1]; // Slave interface 0
|
||||
} __attribute__((packed)) CDC_UNION_1SLAVE_DESCRIPTOR;
|
||||
|
||||
// Line coding structure
|
||||
// Format of the data returned when a GetLineCoding request is received
|
||||
// (usbcdc11.pdf, 6.2.13)
|
||||
typedef struct _CDC_LINE_CODING {
|
||||
uint32_t dwDTERate; // Data terminal rate in bits per second
|
||||
uint8_t bCharFormat; // Number of stop bits
|
||||
uint8_t bParityType; // Parity bit type
|
||||
uint8_t bDataBits; // Number of data bits
|
||||
} __attribute__((packed)) CDC_LINE_CODING;
|
||||
|
||||
// Notification header
|
||||
// Data sent on the notification endpoint must follow this header.
|
||||
// see USB_SETUP_PACKET in file usb.h
|
||||
typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER;
|
||||
|
||||
#endif /* __CDC_H */
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/*******************************************************************
|
||||
Copyright (C) 2009 FreakLabs
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Originally written by Christopher Wang aka Akiba.
|
||||
Please post support questions to the FreakLabs forum.
|
||||
*******************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@file cdc_buf.c
|
||||
@author Christopher Wang (Freaklabs)
|
||||
Modified by: K. Townsend (microBuilder.eu)
|
||||
@date 19 May 2010
|
||||
|
||||
Original code taken from the FreakUSB Open Source USB Device Stack
|
||||
http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
|
||||
|
||||
If it works well, you can thank Akiba at Freaklabs. If it fails
|
||||
miserably, you can blame me (since parts of it it were rather
|
||||
ungraciously modified). :-)
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "cdc_buf.h"
|
||||
|
||||
static cdc_buffer_t cdcfifo;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Gets a pointer to the fifo buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
cdc_buffer_t *cdcGetBuffer()
|
||||
{
|
||||
return &cdcfifo;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initialises the RX FIFO buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferInit()
|
||||
{
|
||||
cdcfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Read one byte out of the RX buffer. This function will return the byte
|
||||
located at the array index of the read pointer, and then increment the
|
||||
read pointer index. If the read pointer exceeds the maximum buffer
|
||||
size, it will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t cdcBufferRead()
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = cdcfifo.buf[cdcfifo.rd_ptr];
|
||||
cdcfifo.rd_ptr = (cdcfifo.rd_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
|
||||
cdcfifo.len--;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Reads x bytes from cdc buffer
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len)
|
||||
{
|
||||
uint32_t counter, actual;
|
||||
counter = actual = 0;
|
||||
|
||||
while(counter != len)
|
||||
{
|
||||
// Make sure we don't exceed buffer limits
|
||||
if (cdcfifo.len > 0)
|
||||
{
|
||||
buf[counter] = cdcBufferRead();
|
||||
actual++;
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return actual;
|
||||
}
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Write one byte into the RX buffer. This function will write one
|
||||
byte into the array index specified by the write pointer and increment
|
||||
the write index. If the write index exceeds the max buffer size, then it
|
||||
will roll over to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferWrite(uint8_t data)
|
||||
{
|
||||
cdcfifo.buf[cdcfifo.wr_ptr] = data;
|
||||
cdcfifo.wr_ptr = (cdcfifo.wr_ptr + 1) % CFG_USBCDC_BUFFERSIZE;
|
||||
cdcfifo.len++;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Clear the fifo read and write pointers and set the length to zero.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void cdcBufferClearFIFO()
|
||||
{
|
||||
cdcfifo.rd_ptr = 0;
|
||||
cdcfifo.wr_ptr = 0;
|
||||
cdcfifo.len = 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Check whether there is any data pending on the RX buffer.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t cdcBufferDataPending()
|
||||
{
|
||||
if (cdcfifo.len != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* Name: cdc_buf.h
|
||||
* Purpose: usb cdc buffer handling
|
||||
* Version: V1.00
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CDC_BUF_H__
|
||||
#define __CDC_BUF_H__
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
// Buffer used for circular fifo
|
||||
typedef struct _cdc_buffer_t
|
||||
{
|
||||
volatile uint8_t len;
|
||||
volatile uint8_t wr_ptr;
|
||||
volatile uint8_t rd_ptr;
|
||||
uint8_t buf[CFG_USBCDC_BUFFERSIZE];
|
||||
} cdc_buffer_t;
|
||||
|
||||
cdc_buffer_t * cdcGetBuffer();
|
||||
void cdcBufferInit();
|
||||
uint8_t cdcBufferRead();
|
||||
uint32_t cdcBufferReadLen(uint8_t* buf, uint32_t len);
|
||||
void cdcBufferWrite(uint8_t data);
|
||||
void cdcBufferClearFIFO();
|
||||
uint8_t cdcBufferDataPending();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,351 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: cdcuser.c
|
||||
* Purpose: USB Communication Device Class User module
|
||||
* Version: V1.10
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#include "usb.h"
|
||||
#include "usbhw.h"
|
||||
#include "usbcfg.h"
|
||||
#include "usbcore.h"
|
||||
#include "cdc.h"
|
||||
#include "cdcuser.h"
|
||||
#include "cdc_buf.h"
|
||||
|
||||
// unsigned char BulkBufIn [64]; // Buffer to store USB IN packet
|
||||
unsigned char BulkBufOut [64]; // Buffer to store USB OUT packet
|
||||
unsigned char NotificationBuf [10];
|
||||
|
||||
CDC_LINE_CODING CDC_LineCoding = {CFG_USBCDC_BAUDRATE, 0, 0, 8};
|
||||
unsigned short CDC_SerialState = 0x0000;
|
||||
unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
We need a buffer for incoming data on USB port because USB receives
|
||||
much faster than UART transmits
|
||||
*---------------------------------------------------------------------------*/
|
||||
/* Buffer masks */
|
||||
#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2)
|
||||
// large enough for file transfer
|
||||
#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul)
|
||||
|
||||
/* Buffer read / write macros */
|
||||
#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)
|
||||
#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))
|
||||
#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])
|
||||
#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx)
|
||||
#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1)
|
||||
#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))
|
||||
|
||||
|
||||
// CDC output buffer
|
||||
typedef struct __CDC_BUF_T
|
||||
{
|
||||
unsigned char data[CDC_BUF_SIZE];
|
||||
volatile unsigned int wrIdx;
|
||||
volatile unsigned int rdIdx;
|
||||
} CDC_BUF_T;
|
||||
|
||||
CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
read data from CDC_OutBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_RdOutBuf (char *buffer, const int *length)
|
||||
{
|
||||
int bytesToRead, bytesRead;
|
||||
|
||||
/* Read *length bytes, block if *bytes are not avaialable */
|
||||
bytesToRead = *length;
|
||||
bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
|
||||
bytesRead = bytesToRead;
|
||||
|
||||
|
||||
// ... add code to check for underrun
|
||||
|
||||
while (bytesToRead--) {
|
||||
*buffer++ = CDC_BUF_RD(CDC_OutBuf);
|
||||
}
|
||||
return (bytesRead);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
write data to CDC_OutBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_WrOutBuf (const char *buffer, int *length)
|
||||
{
|
||||
int bytesToWrite, bytesWritten;
|
||||
|
||||
// Write *length bytes
|
||||
bytesToWrite = *length;
|
||||
bytesWritten = bytesToWrite;
|
||||
|
||||
|
||||
// ... add code to check for overwrite
|
||||
|
||||
while (bytesToWrite) {
|
||||
CDC_BUF_WR(CDC_OutBuf, *buffer++); // Copy Data to buffer
|
||||
bytesToWrite--;
|
||||
}
|
||||
|
||||
return (bytesWritten);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
check if character(s) are available at CDC_OutBuf
|
||||
*---------------------------------------------------------------------------*/
|
||||
int CDC_OutBufAvailChar (int *availChar)
|
||||
{
|
||||
*availChar = CDC_BUF_COUNT(CDC_OutBuf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
/* end Buffer handling */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC Initialisation
|
||||
Initializes the data structures and serial port
|
||||
Parameters: None
|
||||
Return Value: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void CDC_Init (void)
|
||||
{
|
||||
CDC_DepInEmpty = 1;
|
||||
CDC_SerialState = CDC_GetSerialState();
|
||||
|
||||
CDC_BUF_RESET(CDC_OutBuf);
|
||||
|
||||
// Initialise the CDC buffer. This is required to buffer outgoing
|
||||
// data (MCU to PC) since data can only be sent 64 bytes per frame
|
||||
// with at least 1ms between frames. To see how the buffer is used,
|
||||
// see 'puts' in systeminit.c
|
||||
cdcBufferInit();
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC SendEncapsulatedCommand Request Callback
|
||||
Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
|
||||
Parameters: None (global SetupPacket and EP0Buf)
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_SendEncapsulatedCommand (void)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC GetEncapsulatedResponse Request Callback
|
||||
Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
|
||||
Parameters: None (global SetupPacket and EP0Buf)
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_GetEncapsulatedResponse (void)
|
||||
{
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC SetCommFeature Request Callback
|
||||
Called automatically on CDC Set_COMM_FATURE Request
|
||||
Parameters: FeatureSelector
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector)
|
||||
{
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC GetCommFeature Request Callback
|
||||
Called automatically on CDC Get_COMM_FATURE Request
|
||||
Parameters: FeatureSelector
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector)
|
||||
{
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC ClearCommFeature Request Callback
|
||||
Called automatically on CDC CLEAR_COMM_FATURE Request
|
||||
Parameters: FeatureSelector
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector)
|
||||
{
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC SetLineCoding Request Callback
|
||||
Called automatically on CDC SET_LINE_CODING Request
|
||||
Parameters: none (global SetupPacket and EP0Buf)
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_SetLineCoding (void)
|
||||
{
|
||||
CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0)
|
||||
| (EP0Buf[1] << 8)
|
||||
| (EP0Buf[2] << 16)
|
||||
| (EP0Buf[3] << 24);
|
||||
CDC_LineCoding.bCharFormat = EP0Buf[4];
|
||||
CDC_LineCoding.bParityType = EP0Buf[5];
|
||||
CDC_LineCoding.bDataBits = EP0Buf[6];
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC GetLineCoding Request Callback
|
||||
Called automatically on CDC GET_LINE_CODING Request
|
||||
Parameters: None (global SetupPacket and EP0Buf)
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_GetLineCoding (void)
|
||||
{
|
||||
EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF;
|
||||
EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF;
|
||||
EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;
|
||||
EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;
|
||||
EP0Buf[4] = CDC_LineCoding.bCharFormat;
|
||||
EP0Buf[5] = CDC_LineCoding.bParityType;
|
||||
EP0Buf[6] = CDC_LineCoding.bDataBits;
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC SetControlLineState Request Callback
|
||||
Called automatically on CDC SET_CONTROL_LINE_STATE Request
|
||||
Parameters: ControlSignalBitmap
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) {
|
||||
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC SendBreak Request Callback
|
||||
Called automatically on CDC Set_COMM_FATURE Request
|
||||
Parameters: 0xFFFF start of Break
|
||||
0x0000 stop of Break
|
||||
0x#### Duration of Break
|
||||
Return Value: TRUE - Success, FALSE - Error
|
||||
*---------------------------------------------------------------------------*/
|
||||
uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
|
||||
|
||||
/* ... add code to handle request */
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC_BulkIn call on DataIn Request
|
||||
Parameters: none
|
||||
Return Value: none
|
||||
*---------------------------------------------------------------------------*/
|
||||
void CDC_BulkIn(void)
|
||||
{
|
||||
// int numBytesRead, numBytesAvail;
|
||||
//
|
||||
// // ToDo: Modify BulkIn to send incoming data to USB
|
||||
//
|
||||
// ser_AvailChar (&numBytesAvail);
|
||||
//
|
||||
// // ... add code to check for overwrite
|
||||
//
|
||||
// numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);
|
||||
//
|
||||
// // send over USB
|
||||
// if (numBytesRead > 0) {
|
||||
// USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
|
||||
// }
|
||||
// else {
|
||||
// CDC_DepInEmpty = 1;
|
||||
// }
|
||||
//
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CDC_BulkOut call on DataOut Request
|
||||
Parameters: none
|
||||
Return Value: none
|
||||
*---------------------------------------------------------------------------*/
|
||||
void CDC_BulkOut(void)
|
||||
{
|
||||
int numBytesRead;
|
||||
|
||||
// get data from USB into intermediate buffer
|
||||
numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]);
|
||||
|
||||
// ... add code to check for overwrite
|
||||
|
||||
// store data in a buffer to transmit it over serial interface
|
||||
CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
|
||||
Parameters: none
|
||||
Return Value: SerialState as defined in usbcdc11.pdf
|
||||
*---------------------------------------------------------------------------*/
|
||||
unsigned short CDC_GetSerialState (void)
|
||||
{
|
||||
CDC_SerialState = 0;
|
||||
|
||||
return (CDC_SerialState);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
|
||||
*---------------------------------------------------------------------------*/
|
||||
void CDC_NotificationIn (void)
|
||||
{
|
||||
NotificationBuf[0] = 0xA1; // bmRequestType
|
||||
NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE)
|
||||
NotificationBuf[2] = 0x00; // wValue
|
||||
NotificationBuf[3] = 0x00;
|
||||
NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first)
|
||||
NotificationBuf[5] = 0x00;
|
||||
NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
|
||||
NotificationBuf[7] = 0x00;
|
||||
NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
|
||||
NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF;
|
||||
|
||||
USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: cdcuser.h
|
||||
* Purpose: USB Communication Device Class User module Definitions
|
||||
* Version: V1.10
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CDCUSER_H__
|
||||
#define __CDCUSER_H__
|
||||
|
||||
/* CDC buffer handling */
|
||||
extern int CDC_RdOutBuf (char *buffer, const int *length);
|
||||
extern int CDC_WrOutBuf (const char *buffer, int *length);
|
||||
extern int CDC_OutBufAvailChar (int *availChar);
|
||||
|
||||
|
||||
/* CDC Data In/Out Endpoint Address */
|
||||
#define CDC_DEP_IN 0x83
|
||||
#define CDC_DEP_OUT 0x03
|
||||
|
||||
/* CDC Communication In Endpoint Address */
|
||||
#define CDC_CEP_IN 0x81
|
||||
|
||||
/* CDC Requests Callback Functions */
|
||||
extern uint32_t CDC_SendEncapsulatedCommand (void);
|
||||
extern uint32_t CDC_GetEncapsulatedResponse (void);
|
||||
extern uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector);
|
||||
extern uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector);
|
||||
extern uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector);
|
||||
extern uint32_t CDC_GetLineCoding (void);
|
||||
extern uint32_t CDC_SetLineCoding (void);
|
||||
extern uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap);
|
||||
extern uint32_t CDC_SendBreak (unsigned short wDurationOfBreak);
|
||||
|
||||
/* CDC Bulk Callback Functions */
|
||||
extern void CDC_BulkIn (void);
|
||||
extern void CDC_BulkOut (void);
|
||||
|
||||
/* CDC Notification Callback Function */
|
||||
extern void CDC_NotificationIn (void);
|
||||
|
||||
/* CDC Initialization Function */
|
||||
extern void CDC_Init (void);
|
||||
|
||||
/* CDC prepare the SERAIAL_STATE */
|
||||
extern unsigned short CDC_GetSerialState (void);
|
||||
|
||||
/* flow control */
|
||||
extern unsigned short CDC_DepInEmpty; // DataEndPoint IN empty
|
||||
|
||||
#endif /* __CDCUSER_H__ */
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*****************************************************************************
|
||||
* config.h: config file for usbcdc example for NXP LPC13xx Family
|
||||
* Microprocessors
|
||||
*
|
||||
* Copyright(C) 2008, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* History
|
||||
* 2008.07.19 ver 1.00 Preliminary version, first Release
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
Overview:
|
||||
This example shows how to use the USB driver to implement a CDC class USB peripheral.
|
||||
To run this example, you must attach a USB cable to the board. See
|
||||
the "Getting Started Guide" appendix for details.
|
||||
|
||||
How to use:
|
||||
Click the debug toolbar button.
|
||||
Click the go button.
|
||||
Plug the LPCXpresso's target side into a PC using a USB cable retrofit
|
||||
or a 3rd party base board.
|
||||
|
||||
* You should be able to see a new COM port on your PC.
|
||||
*/
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#define USB_VENDOR_ID CFG_USB_VID // Vendor ID
|
||||
#define USB_PROD_ID CFG_USB_PID // Product ID
|
||||
#define USB_DEVICE 0x0100 // Device ID
|
||||
|
||||
#define LED_PORT 0 // Port for led
|
||||
#define LED_BIT 7 // Bit on port for led
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
** End Of File
|
||||
*********************************************************************************/
|
|
@ -0,0 +1,228 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usb.h
|
||||
* Purpose: USB Definitions
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
|
||||
typedef union {
|
||||
uint16_t W;
|
||||
struct {
|
||||
uint8_t L;
|
||||
uint8_t H;
|
||||
} __attribute__((packed)) WB;
|
||||
} __attribute__((packed)) WORD_BYTE;
|
||||
|
||||
|
||||
/* bmRequestType.Dir */
|
||||
#define REQUEST_HOST_TO_DEVICE 0
|
||||
#define REQUEST_DEVICE_TO_HOST 1
|
||||
|
||||
/* bmRequestType.Type */
|
||||
#define REQUEST_STANDARD 0
|
||||
#define REQUEST_CLASS 1
|
||||
#define REQUEST_VENDOR 2
|
||||
#define REQUEST_RESERVED 3
|
||||
|
||||
/* bmRequestType.Recipient */
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
|
||||
/* bmRequestType Definition */
|
||||
typedef union _REQUEST_TYPE {
|
||||
struct _BM {
|
||||
uint8_t Recipient : 5;
|
||||
uint8_t Type : 2;
|
||||
uint8_t Dir : 1;
|
||||
} __attribute__((packed)) BM;
|
||||
uint8_t B;
|
||||
} __attribute__((packed)) REQUEST_TYPE;
|
||||
|
||||
/* USB Standard Request Codes */
|
||||
#define USB_REQUEST_GET_STATUS 0
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1
|
||||
#define USB_REQUEST_SET_FEATURE 3
|
||||
#define USB_REQUEST_SET_ADDRESS 5
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9
|
||||
#define USB_REQUEST_GET_INTERFACE 10
|
||||
#define USB_REQUEST_SET_INTERFACE 11
|
||||
#define USB_REQUEST_SYNC_FRAME 12
|
||||
|
||||
/* USB GET_STATUS Bit Values */
|
||||
#define USB_GETSTATUS_SELF_POWERED 0x01
|
||||
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
|
||||
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
|
||||
|
||||
/* USB Standard Feature selectors */
|
||||
#define USB_FEATURE_ENDPOINT_STALL 0
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||
|
||||
/* USB Default Control Pipe Setup Packet */
|
||||
typedef struct _USB_SETUP_PACKET {
|
||||
REQUEST_TYPE bmRequestType;
|
||||
uint8_t bRequest;
|
||||
WORD_BYTE wValue;
|
||||
WORD_BYTE wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__((packed)) USB_SETUP_PACKET;
|
||||
|
||||
|
||||
/* USB Descriptor Types */
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
||||
#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
|
||||
#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
|
||||
#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
|
||||
#define USB_OTG_DESCRIPTOR_TYPE 9
|
||||
#define USB_DEBUG_DESCRIPTOR_TYPE 10
|
||||
#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
|
||||
|
||||
/* USB Device Classes */
|
||||
#define USB_DEVICE_CLASS_RESERVED 0x00
|
||||
#define USB_DEVICE_CLASS_AUDIO 0x01
|
||||
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
|
||||
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
|
||||
#define USB_DEVICE_CLASS_MONITOR 0x04
|
||||
#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
|
||||
#define USB_DEVICE_CLASS_POWER 0x06
|
||||
#define USB_DEVICE_CLASS_PRINTER 0x07
|
||||
#define USB_DEVICE_CLASS_STORAGE 0x08
|
||||
#define USB_DEVICE_CLASS_HUB 0x09
|
||||
#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
|
||||
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
|
||||
|
||||
/* bmAttributes in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWERED_MASK 0x40
|
||||
#define USB_CONFIG_BUS_POWERED 0x80
|
||||
#define USB_CONFIG_SELF_POWERED 0xC0
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
||||
|
||||
/* bMaxPower in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
|
||||
|
||||
/* bEndpointAddress in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
||||
|
||||
/* bmAttributes in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
||||
#define USB_ENDPOINT_SYNC_MASK 0x0C
|
||||
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
|
||||
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
|
||||
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
|
||||
#define USB_ENDPOINT_USAGE_MASK 0x30
|
||||
#define USB_ENDPOINT_USAGE_DATA 0x00
|
||||
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
|
||||
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
|
||||
#define USB_ENDPOINT_USAGE_RESERVED 0x30
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
typedef struct _USB_DEVICE_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
|
||||
|
||||
/* USB 2.0 Device Qualifier Descriptor */
|
||||
typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
uint8_t bReserved;
|
||||
} __attribute__((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Configuration Descriptor */
|
||||
typedef struct _USB_CONFIGURATION_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Interface Descriptor */
|
||||
typedef struct _USB_INTERFACE_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Endpoint Descriptor */
|
||||
typedef struct _USB_ENDPOINT_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
/* USB String Descriptor */
|
||||
typedef struct _USB_STRING_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bString/*[]*/;
|
||||
} __attribute__((packed)) USB_STRING_DESCRIPTOR;
|
||||
|
||||
/* USB Common Descriptor */
|
||||
typedef struct _USB_COMMON_DESCRIPTOR {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
} __attribute__((packed)) USB_COMMON_DESCRIPTOR;
|
||||
|
||||
|
||||
#endif /* __USB_H__ */
|
|
@ -0,0 +1,157 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbcfg.h
|
||||
* Purpose: USB Custom Configuration
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*----------------------------------------------------------------------------
|
||||
* History:
|
||||
* V1.20 Added vendor specific support
|
||||
* V1.00 Initial Version
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBCFG_H__
|
||||
#define __USBCFG_H__
|
||||
|
||||
|
||||
//*** <<< Use Configuration Wizard in Context Menu >>> ***
|
||||
|
||||
|
||||
/*
|
||||
// <h> USB Configuration
|
||||
// <o0> USB Power
|
||||
// <i> Default Power Setting
|
||||
// <0=> Bus-powered
|
||||
// <1=> Self-powered
|
||||
// <o1> Max Number of Interfaces <1-256>
|
||||
// <o2> Max Number of Endpoints <1-32>
|
||||
// <o3> Max Endpoint 0 Packet Size
|
||||
// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
|
||||
// <e4> DMA Transfer
|
||||
// <i> Use DMA for selected Endpoints
|
||||
// <o5.0> Endpoint 0 Out
|
||||
// <o5.1> Endpoint 0 In
|
||||
// <o5.2> Endpoint 1 Out
|
||||
// <o5.3> Endpoint 1 In
|
||||
// <o5.4> Endpoint 2 Out
|
||||
// <o5.5> Endpoint 2 In
|
||||
// <o5.6> Endpoint 3 Out
|
||||
// <o5.7> Endpoint 3 In
|
||||
// <o5.8> Endpoint 4 Out
|
||||
// <o5.9> Endpoint 4 In
|
||||
// </e>
|
||||
// </h>
|
||||
*/
|
||||
|
||||
#define USB_POWER 0
|
||||
#define USB_IF_NUM 1
|
||||
#define USB_LOGIC_EP_NUM 5
|
||||
#define USB_EP_NUM 10
|
||||
#define USB_MAX_PACKET0 64
|
||||
|
||||
/*
|
||||
// <h> USB Event Handlers
|
||||
// <h> Device Events
|
||||
// <o0.0> Power Event
|
||||
// <o1.0> Reset Event
|
||||
// <o2.0> Suspend Event
|
||||
// <o3.0> Resume Event
|
||||
// <o4.0> Remote Wakeup Event
|
||||
// <o5.0> Start of Frame Event
|
||||
// <o6.0> Error Event
|
||||
// </h>
|
||||
// <h> Endpoint Events
|
||||
// <o7.0> Endpoint 0 Event
|
||||
// <o7.1> Endpoint 1 Event
|
||||
// <o7.2> Endpoint 2 Event
|
||||
// <o7.3> Endpoint 3 Event
|
||||
// <o7.4> Endpoint 4 Event
|
||||
// <o7.5> Endpoint 5 Event
|
||||
// <o7.6> Endpoint 6 Event
|
||||
// <o7.7> Endpoint 7 Event
|
||||
// <o7.8> Endpoint 8 Event
|
||||
// <o7.9> Endpoint 9 Event
|
||||
// <o7.10> Endpoint 10 Event
|
||||
// <o7.11> Endpoint 11 Event
|
||||
// <o7.12> Endpoint 12 Event
|
||||
// <o7.13> Endpoint 13 Event
|
||||
// <o7.14> Endpoint 14 Event
|
||||
// <o7.15> Endpoint 15 Event
|
||||
// </h>
|
||||
// <h> USB Core Events
|
||||
// <o8.0> Set Configuration Event
|
||||
// <o9.0> Set Interface Event
|
||||
// <o10.0> Set/Clear Feature Event
|
||||
// </h>
|
||||
// </h>
|
||||
*/
|
||||
|
||||
#define USB_POWER_EVENT 0
|
||||
#define USB_RESET_EVENT 1
|
||||
#define USB_SUSPEND_EVENT 1
|
||||
#define USB_RESUME_EVENT 1
|
||||
#define USB_WAKEUP_EVENT 0
|
||||
#define USB_SOF_EVENT 1
|
||||
#define USB_ERROR_EVENT 0
|
||||
#define USB_EP_EVENT 0x000B
|
||||
#define USB_CONFIGURE_EVENT 1
|
||||
#define USB_INTERFACE_EVENT 0
|
||||
#define USB_FEATURE_EVENT 0
|
||||
|
||||
|
||||
/*
|
||||
// <e0> USB Class Support
|
||||
// <i> enables USB Class specific Requests
|
||||
// <e1> Human Interface Device (HID)
|
||||
// <o2> Interface Number <0-255>
|
||||
// </e>
|
||||
// <e3> Mass Storage
|
||||
// <o4> Interface Number <0-255>
|
||||
// </e>
|
||||
// <e5> Audio Device
|
||||
// <o6> Control Interface Number <0-255>
|
||||
// <o7> Streaming Interface 1 Number <0-255>
|
||||
// <o8> Streaming Interface 2 Number <0-255>
|
||||
// </e>
|
||||
// <e9> Communication Device
|
||||
// <o10> Control Interface Number <0-255>
|
||||
// <o11> Bulk Interface Number <0-255>
|
||||
// <o12> Max Communication Device Buffer Size
|
||||
// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes
|
||||
// </e>
|
||||
// </e>
|
||||
*/
|
||||
|
||||
#define USB_CLASS 1
|
||||
#define USB_HID 0
|
||||
#define USB_HID_IF_NUM 0
|
||||
#define USB_MSC 0
|
||||
#define USB_MSC_IF_NUM 0
|
||||
#define USB_AUDIO 0
|
||||
#define USB_ADC_CIF_NUM 0
|
||||
#define USB_ADC_SIF1_NUM 1
|
||||
#define USB_ADC_SIF2_NUM 2
|
||||
#define USB_CDC 1
|
||||
#define USB_CDC_CIF_NUM 0
|
||||
#define USB_CDC_DIF_NUM 1
|
||||
#define USB_CDC_BUFSIZE CFG_USBCDC_BUFSIZE
|
||||
|
||||
/*
|
||||
// <e0> USB Vendor Support
|
||||
// <i> enables USB Vendor specific Requests
|
||||
// </e>
|
||||
*/
|
||||
#define USB_VENDOR 0
|
||||
|
||||
|
||||
#endif /* __USBCFG_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,88 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbcore.h
|
||||
* Purpose: USB Core Definitions
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBCORE_H__
|
||||
#define __USBCORE_H__
|
||||
|
||||
#include "usbcfg.h"
|
||||
|
||||
/* USB Endpoint Data Structure */
|
||||
typedef struct _USB_EP_DATA {
|
||||
uint8_t *pData;
|
||||
uint16_t Count;
|
||||
} USB_EP_DATA;
|
||||
|
||||
/* USB Core Global Variables */
|
||||
extern uint16_t USB_DeviceStatus;
|
||||
extern uint8_t USB_DeviceAddress;
|
||||
volatile extern uint8_t USB_Configuration;
|
||||
extern uint32_t USB_EndPointMask;
|
||||
extern uint32_t USB_EndPointHalt;
|
||||
extern uint32_t USB_EndPointStall;
|
||||
extern uint8_t USB_AltSetting[USB_IF_NUM];
|
||||
|
||||
|
||||
/* USB Endpoint 0 Buffer */
|
||||
extern uint8_t EP0Buf[USB_MAX_PACKET0];
|
||||
|
||||
/* USB Endpoint 0 Data Info */
|
||||
extern USB_EP_DATA EP0Data;
|
||||
|
||||
/* USB Setup Packet */
|
||||
extern USB_SETUP_PACKET SetupPacket;
|
||||
|
||||
/* USB Core Functions */
|
||||
extern void USB_ResetCore (void);
|
||||
|
||||
/* Newer C compilers make it really difficult to add
|
||||
* an integer to a pointer */
|
||||
static inline void UsbAddPtr(void **vpptr, uint32_t n);
|
||||
|
||||
/*
|
||||
* Add a number of bytes to a pointer's address
|
||||
* Harder than you might think. Some compilers say:
|
||||
* Expected an lvalue -- Assignment expects its first operand to be
|
||||
* an lvalue. Please note that a cast removes the lvaluedness of an
|
||||
* expression.
|
||||
*
|
||||
* vpptr = void pointer to pointer
|
||||
* n = number of bytes to add to pointer
|
||||
* Call looks like: AddPtr((void **)&myPointer, 8);
|
||||
*/
|
||||
static inline void UsbAddPtr(void **vpptr, uint32_t n)
|
||||
{
|
||||
/* Declare a pointer to a pointer to a byte. Only a byte pointer
|
||||
* can be incremented by a number of bytes. Other pointers will
|
||||
* increment by a multiple of what they point to.
|
||||
*/
|
||||
uint8_t **bpptr;
|
||||
|
||||
/* Convert our void pointer to a pointer to a byte pointer to a pointer */
|
||||
bpptr = (uint8_t **)vpptr;
|
||||
|
||||
/* Add 'n' bytes to our pointer value */
|
||||
(*bpptr) += n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __USBCORE_H__ */
|
|
@ -0,0 +1,202 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbdesc.c
|
||||
* Purpose: USB Descriptors
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*----------------------------------------------------------------------------
|
||||
* History:
|
||||
* V1.20 Changed string descriptor handling
|
||||
* V1.00 Initial Version
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include "projectconfig.h"
|
||||
#include "usb.h"
|
||||
#include "cdc.h"
|
||||
#include "usbcfg.h"
|
||||
#include "usbdesc.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
const uint8_t USB_DeviceDescriptor[] = {
|
||||
USB_DEVICE_DESC_SIZE, /* bLength */
|
||||
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL(0x0200), /* 2.0 */ /* bcdUSB */
|
||||
USB_DEVICE_CLASS_COMMUNICATIONS, /* bDeviceClass CDC*/
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_PACKET0, /* bMaxPacketSize0 */
|
||||
WBVAL(USB_VENDOR_ID), /* idVendor */
|
||||
WBVAL(USB_PROD_ID), /* idProduct */
|
||||
WBVAL(USB_DEVICE), /* 1.00 */ /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01 /* bNumConfigurations: one possible configuration*/
|
||||
};
|
||||
|
||||
/* USB Configuration Descriptor */
|
||||
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
|
||||
const uint8_t USB_ConfigDescriptor[] = {
|
||||
/* Configuration 1 */
|
||||
USB_CONFIGUARTION_DESC_SIZE, /* bLength */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL( /* wTotalLength */
|
||||
1*USB_CONFIGUARTION_DESC_SIZE +
|
||||
1*USB_INTERFACE_DESC_SIZE + /* communication interface */
|
||||
0x0013 + /* CDC functions */
|
||||
1*USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
|
||||
1*USB_INTERFACE_DESC_SIZE + /* data interface */
|
||||
2*USB_ENDPOINT_DESC_SIZE /* bulk endpoints */
|
||||
),
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue: 0x01 is used to select this configuration */
|
||||
0x00, /* iConfiguration: no string to describe this configuration */
|
||||
USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */
|
||||
/*USB_CONFIG_REMOTE_WAKEUP*/,
|
||||
USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */
|
||||
/* Interface 0, Alternate Setting 0, Communication class interface descriptor */
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoint used */
|
||||
CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
|
||||
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol: no protocol used */
|
||||
0x5E, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
|
||||
CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
|
||||
WBVAL(CDC_V1_10), /* 1.10 */ /* bcdCDC */
|
||||
/*Call Management Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
|
||||
CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x01, /* bmCapabilities: device handles call management */
|
||||
0x01, /* bDataInterface: CDC data IF ID */
|
||||
/*Abstract Control Management Functional Descriptor*/
|
||||
0x04, /* bFunctionLength */
|
||||
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
|
||||
CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
|
||||
/*Union Functional Descriptor*/
|
||||
0x05, /* bFunctionLength */
|
||||
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
|
||||
CDC_UNION, /* bDescriptorSubtype: Union func desc */
|
||||
USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
|
||||
USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
|
||||
/*Endpoint 1 Descriptor*/ /* event notification (optional) */
|
||||
USB_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
USB_ENDPOINT_IN(1), /* bEndpointAddress */
|
||||
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
|
||||
WBVAL(0x0010), /* wMaxPacketSize */
|
||||
0x02, /* 2ms */ /* bInterval */
|
||||
/* Interface 1, Alternate Setting 0, Data class interface descriptor*/
|
||||
USB_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: no alternate setting */
|
||||
0x02, /* bNumEndpoints: two endpoints used */
|
||||
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
|
||||
0x00, /* bInterfaceSubClass: no subclass available */
|
||||
0x00, /* bInterfaceProtocol: no protocol used */
|
||||
0x5E, /* iInterface: */
|
||||
/* Endpoint, EP3 Bulk Out */
|
||||
USB_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
USB_ENDPOINT_OUT(3), /* bEndpointAddress */
|
||||
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
|
||||
WBVAL(64), /* wMaxPacketSize */
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
/* Endpoint, EP3 Bulk In */
|
||||
USB_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
USB_ENDPOINT_IN(3), /* bEndpointAddress */
|
||||
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
|
||||
WBVAL(64), /* wMaxPacketSize */
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
/* Terminator */
|
||||
0 /* bLength */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* USB String Descriptor (optional) */
|
||||
const uint8_t USB_StringDescriptor[] = {
|
||||
/* Index 0x00: LANGID Codes */
|
||||
0x04, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL(0x0409), /* US English */ /* wLANGID */
|
||||
/* Index 0x01: Manufacturer */
|
||||
(13*2 + 2), /* bLength (13 Char + Type + lenght) */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'M',0,
|
||||
'I',0,
|
||||
'C',0,
|
||||
'R',0,
|
||||
'O',0,
|
||||
'B',0,
|
||||
'U',0,
|
||||
'I',0,
|
||||
'L',0,
|
||||
'D',0,
|
||||
'E',0,
|
||||
'R',0,
|
||||
' ',0,
|
||||
/* Index 0x02: Product */
|
||||
(17*2 + 2), /* bLength ( 17 Char + Type + lenght) */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'L',0,
|
||||
'P',0,
|
||||
'C',0,
|
||||
'1',0,
|
||||
'3',0,
|
||||
'4',0,
|
||||
'3',0,
|
||||
' ',0,
|
||||
'C',0,
|
||||
'O',0,
|
||||
'M',0,
|
||||
' ',0,
|
||||
'P',0,
|
||||
'O',0,
|
||||
'R',0,
|
||||
'T',0,
|
||||
' ',0,
|
||||
/* Index 0x03: Serial Number */
|
||||
(12*2 + 2), /* bLength (12 Char + Type + lenght) */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'D',0,
|
||||
'E',0,
|
||||
'M',0,
|
||||
'O',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
/* Index 0x04: Interface 0, Alternate Setting 0 */
|
||||
( 4*2 + 2), /* bLength (4 Char + Type + lenght) */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'V',0,
|
||||
'C',0,
|
||||
'O',0,
|
||||
'M',0,
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbdesc.h
|
||||
* Purpose: USB Descriptors Definitions
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBDESC_H__
|
||||
#define __USBDESC_H__
|
||||
|
||||
|
||||
#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR))
|
||||
#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
|
||||
#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR))
|
||||
#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR))
|
||||
|
||||
extern const uint8_t USB_DeviceDescriptor[];
|
||||
extern const uint8_t USB_ConfigDescriptor[];
|
||||
extern const uint8_t USB_StringDescriptor[];
|
||||
|
||||
|
||||
#endif /* __USBDESC_H__ */
|
|
@ -0,0 +1,606 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbhw.c
|
||||
* Purpose: USB Hardware Layer Module for Philips LPC17xx
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*----------------------------------------------------------------------------
|
||||
* History:
|
||||
* V1.20 Added USB_ClearEPBuf
|
||||
* V1.00 Initial Version
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "projectconfig.h" /* LPC13xx definitions */
|
||||
#include "usb.h"
|
||||
#include "usbcfg.h"
|
||||
#include "usbreg.h"
|
||||
#include "usbhw.h"
|
||||
#include "usbcore.h"
|
||||
#include "usbuser.h"
|
||||
|
||||
|
||||
/*
|
||||
* USB and IO Clock configuration only.
|
||||
* The same as call PeriClkIOInit(IOCON_USB);
|
||||
* The purpose is to reduce the code space for
|
||||
* overall USB project and reserve code space for
|
||||
* USB debugging.
|
||||
* Parameters: None
|
||||
* Return Value: None
|
||||
*/
|
||||
void USBIOClkConfig( void )
|
||||
{
|
||||
/* Enable AHB clock to the GPIO domain. */
|
||||
SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_GPIO;
|
||||
|
||||
/* Enable Timer32_1, IOCON, and USB blocks */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG);
|
||||
|
||||
// Setup USB clock
|
||||
SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY
|
||||
SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL
|
||||
|
||||
SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE;
|
||||
|
||||
// Wait until the USB clock is updated
|
||||
while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE));
|
||||
|
||||
// Set USB clock to 48MHz (12MHz x 4)
|
||||
SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4);
|
||||
while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked
|
||||
SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT;
|
||||
|
||||
// Set USB pin functions
|
||||
IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK;
|
||||
IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT
|
||||
IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK;
|
||||
IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus
|
||||
IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK;
|
||||
IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay number of clock cycles
|
||||
* Parameters: Delay length
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void delay (uint32_t length )
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
__asm("nop");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Endpoint Physical Address
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: Endpoint Physical Address
|
||||
*/
|
||||
|
||||
uint32_t EPAdr (uint32_t EPNum)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = (EPNum & 0x0F) << 1;
|
||||
if (EPNum & 0x80) {
|
||||
val += 1;
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write Command
|
||||
* Parameters: cmd: Command
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void WrCmd (uint32_t cmd)
|
||||
{
|
||||
USB_DEVINTCLR = CCEMTY_INT;
|
||||
USB_CMDCODE = cmd;
|
||||
while ((USB_DEVINTST & (CCEMTY_INT | DEV_STAT_INT)) == 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write Command Data
|
||||
* Parameters: cmd: Command
|
||||
* val: Data
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void WrCmdDat (uint32_t cmd, uint32_t val)
|
||||
{
|
||||
WrCmd(cmd);
|
||||
WrCmd(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write Command to Endpoint
|
||||
* Parameters: cmd: Command
|
||||
* val: Data
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void WrCmdEP (uint32_t EPNum, uint32_t cmd)
|
||||
{
|
||||
WrCmd(CMD_SEL_EP(EPAdr(EPNum)));
|
||||
WrCmd(cmd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read Command Data
|
||||
* Parameters: cmd: Command
|
||||
* Return Value: Data Value
|
||||
*/
|
||||
|
||||
uint32_t RdCmdDat (uint32_t cmd)
|
||||
{
|
||||
USB_DEVINTCLR = CCEMTY_INT | CDFULL_INT;
|
||||
USB_CMDCODE = cmd;
|
||||
while ((USB_DEVINTST & (CDFULL_INT | DEV_STAT_INT)) == 0);
|
||||
return (USB_CMDDATA);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Initialize Function
|
||||
* Called by the User to initialize USB
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Init (void)
|
||||
{
|
||||
// Setup USB clock and pins
|
||||
USBIOClkConfig();
|
||||
|
||||
#if USB_FIQ_EVENT
|
||||
/* It's important that only BULK and FRAME(ISO) can be routed
|
||||
to FIQ. */
|
||||
USB_DEVFIQSEL = 0x01; /* SOF Use FIQ */
|
||||
|
||||
/* Enable the USB Interrupt */
|
||||
NVIC_EnableIRQ(USB_FIQn);
|
||||
#endif
|
||||
|
||||
/* Enable the USB Interrupt */
|
||||
NVIC_EnableIRQ(USB_IRQn);
|
||||
|
||||
USB_Reset();
|
||||
USB_SetAddress(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Connect Function
|
||||
* Called by the User to Connect/Disconnect USB
|
||||
* Parameters: con: Connect/Disconnect
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Connect (uint32_t con)
|
||||
{
|
||||
WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Reset Function
|
||||
* Called automatically on USB Reset
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Reset (void)
|
||||
{
|
||||
USB_DEVINTCLR = 0x000FFFFF;
|
||||
/* Enable all eight(8) EPs, note: EP won't be ready until it's
|
||||
configured/enabled when device sending SetEPStatus command
|
||||
to the command engine. */
|
||||
USB_DEVINTEN = DEV_STAT_INT | (0xFF<<1) |
|
||||
(USB_SOF_EVENT ? FRAME_INT : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Suspend Function
|
||||
* Called automatically on USB Suspend
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Suspend (void)
|
||||
{
|
||||
/* Performed by Hardware */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Resume Function
|
||||
* Called automatically on USB Resume
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Resume (void)
|
||||
{
|
||||
/* Performed by Hardware */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Remote Wakeup Function
|
||||
* Called automatically on USB Remote Wakeup
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_WakeUp (void)
|
||||
{
|
||||
if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP)
|
||||
{
|
||||
WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Remote Wakeup Configuration Function
|
||||
* Parameters: cfg: Enable/Disable
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_WakeUpCfg (uint32_t cfg)
|
||||
{
|
||||
cfg = cfg; /* Not needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Set Address Function
|
||||
* Parameters: adr: USB Address
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_SetAddress (uint32_t adr)
|
||||
{
|
||||
WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */
|
||||
WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Configure Function
|
||||
* Parameters: cfg: Configure/Deconfigure
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_Configure (uint32_t cfg)
|
||||
{
|
||||
WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure USB Endpoint according to Descriptor
|
||||
* Parameters: pEPD: Pointer to Endpoint Descriptor
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set Direction for USB Control Endpoint
|
||||
* Parameters: dir: Out (dir == 0), In (dir <> 0)
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_DirCtrlEP (uint32_t dir)
|
||||
{
|
||||
dir = dir; /* Not needed */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable USB Endpoint
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_EnableEP (uint32_t EPNum)
|
||||
{
|
||||
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable USB Endpoint
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_DisableEP (uint32_t EPNum)
|
||||
{
|
||||
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset USB Endpoint
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_ResetEP (uint32_t EPNum)
|
||||
{
|
||||
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set Stall for USB Endpoint
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_SetStallEP (uint32_t EPNum)
|
||||
{
|
||||
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear Stall for USB Endpoint
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_ClrStallEP (uint32_t EPNum)
|
||||
{
|
||||
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear USB Endpoint Buffer
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
void USB_ClearEPBuf (uint32_t EPNum)
|
||||
{
|
||||
WrCmdEP(EPNum, CMD_CLR_BUF);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read USB Endpoint Data
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* pData: Pointer to Data Buffer
|
||||
* Return Value: Number of bytes read
|
||||
*/
|
||||
|
||||
uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData)
|
||||
{
|
||||
uint32_t cnt, n;
|
||||
|
||||
USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
|
||||
/* 3 clock cycles to fetch the packet length from RAM. */
|
||||
delay( 5 );
|
||||
|
||||
do
|
||||
{
|
||||
cnt = USB_RXPLEN;
|
||||
} while ((cnt & PKT_DV) == 0);
|
||||
cnt &= PKT_LNGTH_MASK;
|
||||
|
||||
for (n = 0; n < (cnt + 3) / 4; n++)
|
||||
{
|
||||
*((uint32_t __attribute__((packed)) *)pData) = USB_RXDATA;
|
||||
pData += 4;
|
||||
}
|
||||
|
||||
USB_CTRL = 0;
|
||||
|
||||
if ((EPNum & 0x80) != 0x04)
|
||||
{ /* Non-Isochronous Endpoint */
|
||||
WrCmdEP(EPNum, CMD_CLR_BUF);
|
||||
}
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write USB Endpoint Data
|
||||
* Parameters: EPNum: Endpoint Number
|
||||
* EPNum.0..3: Address
|
||||
* EPNum.7: Dir
|
||||
* pData: Pointer to Data Buffer
|
||||
* cnt: Number of bytes to write
|
||||
* Return Value: Number of bytes written
|
||||
*/
|
||||
|
||||
uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt)
|
||||
{
|
||||
uint32_t n;
|
||||
|
||||
USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
|
||||
/* 3 clock cycles to fetch the packet length from RAM. */
|
||||
delay( 5 );
|
||||
USB_TXPLEN = cnt;
|
||||
|
||||
for (n = 0; n < (cnt + 3) / 4; n++)
|
||||
{
|
||||
USB_TXDATA = *((uint32_t __attribute__((packed)) *)pData);
|
||||
pData += 4;
|
||||
}
|
||||
|
||||
USB_CTRL = 0;
|
||||
|
||||
WrCmdEP(EPNum, CMD_VALID_BUF);
|
||||
|
||||
return (cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get USB Last Frame Number
|
||||
* Parameters: None
|
||||
* Return Value: Frame Number
|
||||
*/
|
||||
|
||||
uint32_t USB_GetFrame (void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
WrCmd(CMD_RD_FRAME);
|
||||
val = RdCmdDat(DAT_RD_FRAME);
|
||||
val = val | (RdCmdDat(DAT_RD_FRAME) << 8);
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Interrupt Service Routine
|
||||
*/
|
||||
|
||||
#ifdef CFG_USBCDC
|
||||
void USB_IRQHandler (void)
|
||||
{
|
||||
uint32_t disr, val, n, m;
|
||||
|
||||
disr = USB_DEVINTST; /* Device Interrupt Status */
|
||||
USB_DEVINTCLR = disr;
|
||||
|
||||
/* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
|
||||
if (disr & DEV_STAT_INT)
|
||||
{
|
||||
WrCmd(CMD_GET_DEV_STAT);
|
||||
val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */
|
||||
if (val & DEV_RST) { /* Reset */
|
||||
USB_Reset();
|
||||
#if USB_RESET_EVENT
|
||||
USB_Reset_Event();
|
||||
#endif
|
||||
}
|
||||
if (val & DEV_CON_CH) { /* Connect change */
|
||||
#if USB_POWER_EVENT
|
||||
USB_Power_Event(val & DEV_CON);
|
||||
#endif
|
||||
}
|
||||
if (val & DEV_SUS_CH) { /* Suspend/Resume */
|
||||
if (val & DEV_SUS) { /* Suspend */
|
||||
USB_Suspend();
|
||||
#if USB_SUSPEND_EVENT
|
||||
USB_Suspend_Event();
|
||||
#endif
|
||||
} else { /* Resume */
|
||||
USB_Resume();
|
||||
#if USB_RESUME_EVENT
|
||||
USB_Resume_Event();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
goto isr_end;
|
||||
}
|
||||
|
||||
#if USB_SOF_EVENT
|
||||
/* Start of Frame Interrupt */
|
||||
if (disr & FRAME_INT)
|
||||
{
|
||||
USB_DEVINTCLR = FRAME_INT;
|
||||
USB_SOF_Event();
|
||||
// SOFIRQCount++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USB_ERROR_EVENT
|
||||
/* NO error interrupt anymore, below code can be used
|
||||
as example to get error status from command engine. */
|
||||
/* Error Interrupt */
|
||||
if (disr & ERR_INT)
|
||||
{
|
||||
WrCmd(CMD_RD_ERR_STAT);
|
||||
val = RdCmdDat(DAT_RD_ERR_STAT);
|
||||
USB_Error_Event(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Endpoint's Interrupt */
|
||||
if (disr & (0xFF<<1)) {
|
||||
/* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */
|
||||
for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
|
||||
/* skip frame interrupt at bit 0 in disr */
|
||||
// if (disr & ((1 << n)<<1)) {
|
||||
if ((disr>>1) & (1 << n)) {
|
||||
m = n >> 1;
|
||||
/* clear EP interrupt by sending cmd to the command engine. */
|
||||
WrCmd(CMD_SEL_EP_CLRI(n));
|
||||
val = RdCmdDat(DAT_SEL_EP_CLRI(n));
|
||||
if ((n & 1) == 0) { /* OUT Endpoint */
|
||||
if (n == 0) { /* Control OUT Endpoint */
|
||||
if (val & EP_SEL_STP) { /* Setup Packet */
|
||||
if (USB_P_EP[0]) {
|
||||
USB_P_EP[0](USB_EVT_SETUP);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (USB_P_EP[m]) {
|
||||
USB_P_EP[m](USB_EVT_OUT);
|
||||
}
|
||||
} else { /* IN Endpoint */
|
||||
if (USB_P_EP[m]) {
|
||||
USB_P_EP[m](USB_EVT_IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
isr_end:
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbhw.h
|
||||
* Purpose: USB Hardware Layer Definitions
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*----------------------------------------------------------------------------
|
||||
* History:
|
||||
* V1.20 Added USB_ClearEPBuf
|
||||
* V1.00 Initial Version
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBHW_H__
|
||||
#define __USBHW_H__
|
||||
|
||||
|
||||
/* USB Error Codes */
|
||||
#define USB_ERR_PID 0x0001 /* PID Error */
|
||||
#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */
|
||||
#define USB_ERR_DCRC 0x0004 /* Data CRC Error */
|
||||
#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */
|
||||
#define USB_ERR_EOP 0x0010 /* End of Packet Error */
|
||||
#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */
|
||||
#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */
|
||||
#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */
|
||||
|
||||
/* USB Hardware Functions */
|
||||
extern void USBIOClkConfig (void);
|
||||
extern void USB_Init (void);
|
||||
extern void USB_Connect (uint32_t con);
|
||||
extern void USB_Reset (void);
|
||||
extern void USB_Suspend (void);
|
||||
extern void USB_Resume (void);
|
||||
extern void USB_WakeUp (void);
|
||||
extern void USB_WakeUpCfg (uint32_t cfg);
|
||||
extern void USB_SetAddress (uint32_t adr);
|
||||
extern void USB_Configure (uint32_t cfg);
|
||||
extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD);
|
||||
extern void USB_DirCtrlEP (uint32_t dir);
|
||||
extern void USB_EnableEP (uint32_t EPNum);
|
||||
extern void USB_DisableEP (uint32_t EPNum);
|
||||
extern void USB_ResetEP (uint32_t EPNum);
|
||||
extern void USB_SetStallEP (uint32_t EPNum);
|
||||
extern void USB_ClrStallEP (uint32_t EPNum);
|
||||
extern void USB_ClearEPBuf (uint32_t EPNum);
|
||||
extern uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData);
|
||||
extern uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt);
|
||||
extern uint32_t USB_GetFrame(void);
|
||||
extern void USB_IRQHandler (void);
|
||||
|
||||
|
||||
#endif /* __USBHW_H__ */
|
|
@ -0,0 +1,134 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: USBREG.H
|
||||
* Purpose: USB Hardware Layer Definitions for NXP LPC13xx
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBREG_H
|
||||
#define __USBREG_H
|
||||
|
||||
/* Device Interrupt Bit Definitions */
|
||||
#define FRAME_INT (0x1<<0)
|
||||
#define EP0_INT (0x1<<1)
|
||||
#define EP1_INT (0x1<<2)
|
||||
#define EP2_INT (0x1<<3)
|
||||
#define EP3_INT (0x1<<4)
|
||||
#define EP4_INT (0x1<<5)
|
||||
#define EP5_INT (0x1<<6)
|
||||
#define EP6_INT (0x1<<7)
|
||||
#define EP7_INT (0x1<<8)
|
||||
#define DEV_STAT_INT (0x1<<9)
|
||||
#define CCEMTY_INT (0x1<<10)
|
||||
#define CDFULL_INT (0x1<<11)
|
||||
#define RxENDPKT_INT (0x1<<12)
|
||||
#define TxENDPKT_INT (0x1<<13)
|
||||
|
||||
/* Rx & Tx Packet Length Definitions */
|
||||
#define PKT_LNGTH_MASK 0x000003FF
|
||||
#define PKT_DV 0x00000400
|
||||
#define PKT_RDY 0x00000800
|
||||
|
||||
/* USB Control Definitions */
|
||||
#define CTRL_RD_EN 0x00000001
|
||||
#define CTRL_WR_EN 0x00000002
|
||||
|
||||
/* Command Codes */
|
||||
#define CMD_SET_ADDR 0x00D00500
|
||||
#define CMD_CFG_DEV 0x00D80500
|
||||
#define CMD_SET_MODE 0x00F30500
|
||||
#define CMD_RD_INT 0x00F40500
|
||||
#define DAT_RD_INT 0x00F40200
|
||||
#define CMD_RD_FRAME 0x00F50500
|
||||
#define DAT_RD_FRAME 0x00F50200
|
||||
#define CMD_RD_CHIP_ID 0x00FD0500
|
||||
#define DAT_RD_CHIP_ID 0x00FD0200
|
||||
|
||||
#define CMD_SET_DEV_STAT 0x00FE0500
|
||||
#define CMD_GET_DEV_STAT 0x00FE0500
|
||||
#define DAT_GET_DEV_STAT 0x00FE0200
|
||||
#define CMD_GET_ERR_CODE 0x00FF0500
|
||||
#define DAT_GET_ERR_CODE 0x00FF0200
|
||||
|
||||
#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16))
|
||||
#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
|
||||
#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16))
|
||||
#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
|
||||
#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16))
|
||||
#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16))
|
||||
#define CMD_CLR_BUF 0x00F20500
|
||||
#define CMD_VALID_BUF 0x00FA0500
|
||||
|
||||
/* Device Address Register Definitions */
|
||||
#define DEV_ADDR_MASK 0x7F
|
||||
#define DEV_EN 0x80
|
||||
|
||||
/* Device Configure Register Definitions */
|
||||
#define CONF_DVICE 0x01
|
||||
|
||||
/* Device Mode Register Definitions */
|
||||
#define AP_CLK 0x01
|
||||
#define INAK_CI 0x02
|
||||
#define INAK_CO 0x04
|
||||
#define INAK_AI 0x08
|
||||
#define INAK_AO 0x10
|
||||
|
||||
/* Device Status Register Definitions */
|
||||
#define DEV_CON 0x01
|
||||
#define DEV_CON_CH 0x02
|
||||
#define DEV_SUS 0x04
|
||||
#define DEV_SUS_CH 0x08
|
||||
#define DEV_RST 0x10
|
||||
|
||||
/* Error Code Register Definitions */
|
||||
#define ERR_EC_MASK 0x0F
|
||||
#define ERR_EA 0x10
|
||||
|
||||
/* Error Status Register Definitions */
|
||||
#define ERR_NOERROR 0x00
|
||||
#define ERR_PID_ENCODE 0x01
|
||||
#define ERR_UNKNOWN_PID 0x02
|
||||
#define ERR_UNEXPECT_PKT 0x03
|
||||
#define ERR_TCRC 0x04
|
||||
#define ERR_DCRC 0x05
|
||||
#define ERR_TIMEOUT 0x06
|
||||
#define ERR_BABBIE 0x07
|
||||
#define ERR_EOF_PKT 0x08
|
||||
#define ERR_TX_RX_NAK 0x09
|
||||
#define ERR_SENT_STALL 0x0A
|
||||
#define ERR_BUF_OVERRUN 0x0B
|
||||
#define ERR_SENT_EPT_PKT 0x0C
|
||||
#define ERR_BIT_STUFF 0x0D
|
||||
#define ERR_SYNC 0x0E
|
||||
#define ERR_TOGGLE_BIT 0x0F
|
||||
|
||||
/* Endpoint Select Register Definitions */
|
||||
#define EP_SEL_F 0x01
|
||||
#define EP_SEL_ST 0x02
|
||||
#define EP_SEL_STP 0x04
|
||||
#define EP_SEL_PO 0x08
|
||||
#define EP_SEL_EPN 0x10
|
||||
#define EP_SEL_B_1_FULL 0x20
|
||||
#define EP_SEL_B_2_FULL 0x40
|
||||
|
||||
/* Endpoint Status Register Definitions */
|
||||
#define EP_STAT_ST 0x01
|
||||
#define EP_STAT_DA 0x20
|
||||
#define EP_STAT_RF_MO 0x40
|
||||
#define EP_STAT_CND_ST 0x80
|
||||
|
||||
/* Clear Buffer Register Definitions */
|
||||
#define CLR_BUF_PO 0x01
|
||||
|
||||
#endif /* __USBREG_H */
|
|
@ -0,0 +1,208 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usbuser.c
|
||||
* Purpose: USB Custom User Module
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include "projectconfig.h"
|
||||
|
||||
#include "usb.h"
|
||||
#include "usbcfg.h"
|
||||
#include "usbhw.h"
|
||||
#include "usbcore.h"
|
||||
#include "usbuser.h"
|
||||
#include "cdcuser.h"
|
||||
|
||||
|
||||
/*
|
||||
* USB Power Event Callback
|
||||
* Called automatically on USB Power Event
|
||||
* Parameter: power: On(TRUE)/Off(FALSE)
|
||||
*/
|
||||
|
||||
#if USB_POWER_EVENT
|
||||
void USB_Power_Event (uint32_t power) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Reset Event Callback
|
||||
* Called automatically on USB Reset Event
|
||||
*/
|
||||
|
||||
#if USB_RESET_EVENT
|
||||
void USB_Reset_Event (void) {
|
||||
USB_ResetCore();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Suspend Event Callback
|
||||
* Called automatically on USB Suspend Event
|
||||
*/
|
||||
|
||||
#if USB_SUSPEND_EVENT
|
||||
void USB_Suspend_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Resume Event Callback
|
||||
* Called automatically on USB Resume Event
|
||||
*/
|
||||
|
||||
#if USB_RESUME_EVENT
|
||||
void USB_Resume_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Remote Wakeup Event Callback
|
||||
* Called automatically on USB Remote Wakeup Event
|
||||
*/
|
||||
|
||||
#if USB_WAKEUP_EVENT
|
||||
void USB_WakeUp_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Start of Frame Event Callback
|
||||
* Called automatically on USB Start of Frame Event
|
||||
*/
|
||||
|
||||
#if USB_SOF_EVENT
|
||||
void USB_SOF_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Error Event Callback
|
||||
* Called automatically on USB Error Event
|
||||
* Parameter: error: Error Code
|
||||
*/
|
||||
|
||||
#if USB_ERROR_EVENT
|
||||
void USB_Error_Event (uint32_t error) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Set Configuration Event Callback
|
||||
* Called automatically on USB Set Configuration Request
|
||||
*/
|
||||
|
||||
#if USB_CONFIGURE_EVENT
|
||||
void USB_Configure_Event (void) {
|
||||
|
||||
if (USB_Configuration) { /* Check if USB is configured */
|
||||
/* add your code here */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Set Interface Event Callback
|
||||
* Called automatically on USB Set Interface Request
|
||||
*/
|
||||
|
||||
#if USB_INTERFACE_EVENT
|
||||
void USB_Interface_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* USB Set/Clear Feature Event Callback
|
||||
* Called automatically on USB Set/Clear Feature Request
|
||||
*/
|
||||
|
||||
#if USB_FEATURE_EVENT
|
||||
void USB_Feature_Event (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL)
|
||||
|
||||
/* USB Endpoint Events Callback Pointers */
|
||||
void (* const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = {
|
||||
P_EP(0),
|
||||
P_EP(1),
|
||||
P_EP(2),
|
||||
P_EP(3),
|
||||
P_EP(4),
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* USB Endpoint 1 Event Callback
|
||||
* Called automatically on USB Endpoint 1 Event
|
||||
* Parameter: event
|
||||
*/
|
||||
|
||||
void USB_EndPoint1 (uint32_t event) {
|
||||
uint16_t temp;
|
||||
static uint16_t serialState;
|
||||
|
||||
switch (event) {
|
||||
case USB_EVT_IN:
|
||||
temp = CDC_GetSerialState();
|
||||
if (serialState != temp) {
|
||||
serialState = temp;
|
||||
CDC_NotificationIn(); /* send SERIAL_STATE notification */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Endpoint 2 Event Callback
|
||||
* Called automatically on USB Endpoint 2 Event
|
||||
* Parameter: event
|
||||
*/
|
||||
|
||||
void USB_EndPoint2 (uint32_t event)
|
||||
{
|
||||
event = event;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB Endpoint 3 Event Callback
|
||||
* Called automatically on USB Endpoint 3 Event
|
||||
* Parameter: event
|
||||
*/
|
||||
|
||||
void USB_EndPoint3 (uint32_t event) {
|
||||
switch (event) {
|
||||
case USB_EVT_OUT:
|
||||
CDC_BulkOut (); /* data received from Host */
|
||||
break;
|
||||
case USB_EVT_IN:
|
||||
CDC_BulkIn (); /* data expected from Host */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: USBUSER.H
|
||||
* Purpose: USB Custom User Definitions
|
||||
* Version: V1.10
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2005-2009 Keil Software.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USBUSER_H__
|
||||
#define __USBUSER_H__
|
||||
|
||||
|
||||
/* USB Device Events Callback Functions */
|
||||
extern void USB_Power_Event (uint32_t power);
|
||||
extern void USB_Reset_Event (void);
|
||||
extern void USB_Suspend_Event (void);
|
||||
extern void USB_Resume_Event (void);
|
||||
extern void USB_WakeUp_Event (void);
|
||||
extern void USB_SOF_Event (void);
|
||||
extern void USB_Error_Event (uint32_t error);
|
||||
|
||||
/* USB Endpoint Callback Events */
|
||||
#define USB_EVT_SETUP 1 /* Setup Packet */
|
||||
#define USB_EVT_OUT 2 /* OUT Packet */
|
||||
#define USB_EVT_IN 3 /* IN Packet */
|
||||
#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */
|
||||
#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */
|
||||
#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */
|
||||
#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */
|
||||
|
||||
/* USB Endpoint Events Callback Pointers */
|
||||
extern void (* const USB_P_EP[USB_LOGIC_EP_NUM])(uint32_t event);
|
||||
|
||||
/* USB Endpoint Events Callback Functions */
|
||||
extern void USB_EndPoint0 (uint32_t event);
|
||||
extern void USB_EndPoint1 (uint32_t event);
|
||||
extern void USB_EndPoint2 (uint32_t event);
|
||||
extern void USB_EndPoint3 (uint32_t event);
|
||||
extern void USB_EndPoint4 (uint32_t event);
|
||||
|
||||
/* USB Core Events Callback Functions */
|
||||
extern void USB_Configure_Event (void);
|
||||
extern void USB_Interface_Event (void);
|
||||
extern void USB_Feature_Event (void);
|
||||
|
||||
|
||||
#endif /* __USBUSER_H__ */
|
|
@ -0,0 +1,240 @@
|
|||
/*----------------------------------------------------------------------------
|
||||
* U S B - K e r n e l
|
||||
*----------------------------------------------------------------------------
|
||||
* Name: usb.h
|
||||
* Purpose: USB Definitions
|
||||
* Version: V1.20
|
||||
*----------------------------------------------------------------------------
|
||||
* This software is supplied "AS IS" without any warranties, express,
|
||||
* implied or statutory, including but not limited to the implied
|
||||
* warranties of fitness for purpose, satisfactory quality and
|
||||
* noninfringement. Keil extends you a royalty-free right to reproduce
|
||||
* and distribute executable files created using this software for use
|
||||
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
|
||||
* gives you the right to use this software.
|
||||
*
|
||||
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include "sysdefs.h"
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t W;
|
||||
struct
|
||||
{
|
||||
uint8_t L;
|
||||
uint8_t H;
|
||||
} __attribute__ ((packed)) WB;
|
||||
} __attribute__ ((packed)) WORD_BYTE;
|
||||
|
||||
|
||||
/* bmRequestType.Dir */
|
||||
#define REQUEST_HOST_TO_DEVICE 0
|
||||
#define REQUEST_DEVICE_TO_HOST 1
|
||||
|
||||
/* bmRequestType.Type */
|
||||
#define REQUEST_STANDARD 0
|
||||
#define REQUEST_CLASS 1
|
||||
#define REQUEST_VENDOR 2
|
||||
#define REQUEST_RESERVED 3
|
||||
|
||||
/* bmRequestType.Recipient */
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
|
||||
/* bmRequestType Definition */
|
||||
typedef union _REQUEST_TYPE
|
||||
{
|
||||
struct _BM
|
||||
{
|
||||
uint8_t Recipient : 5;
|
||||
uint8_t Type : 2;
|
||||
uint8_t Dir : 1;
|
||||
} __attribute__ ((packed)) BM;
|
||||
uint8_t B;
|
||||
} __attribute__ ((packed)) REQUEST_TYPE;
|
||||
|
||||
/* USB Standard Request Codes */
|
||||
#define USB_REQUEST_GET_STATUS 0
|
||||
#define USB_REQUEST_CLEAR_FEATURE 1
|
||||
#define USB_REQUEST_SET_FEATURE 3
|
||||
#define USB_REQUEST_SET_ADDRESS 5
|
||||
#define USB_REQUEST_GET_DESCRIPTOR 6
|
||||
#define USB_REQUEST_SET_DESCRIPTOR 7
|
||||
#define USB_REQUEST_GET_CONFIGURATION 8
|
||||
#define USB_REQUEST_SET_CONFIGURATION 9
|
||||
#define USB_REQUEST_GET_INTERFACE 10
|
||||
#define USB_REQUEST_SET_INTERFACE 11
|
||||
#define USB_REQUEST_SYNC_FRAME 12
|
||||
|
||||
/* USB GET_STATUS Bit Values */
|
||||
#define USB_GETSTATUS_SELF_POWERED 0x01
|
||||
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
|
||||
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
|
||||
|
||||
/* USB Standard Feature selectors */
|
||||
#define USB_FEATURE_ENDPOINT_STALL 0
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||
|
||||
/* USB Default Control Pipe Setup Packet */
|
||||
typedef struct _USB_SETUP_PACKET
|
||||
{
|
||||
REQUEST_TYPE bmRequestType;
|
||||
uint8_t bRequest;
|
||||
WORD_BYTE wValue;
|
||||
WORD_BYTE wIndex;
|
||||
uint16_t wLength;
|
||||
} __attribute__ ((packed)) USB_SETUP_PACKET;
|
||||
|
||||
|
||||
/* USB Descriptor Types */
|
||||
#define USB_DEVICE_DESCRIPTOR_TYPE 1
|
||||
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
|
||||
#define USB_STRING_DESCRIPTOR_TYPE 3
|
||||
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
|
||||
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
|
||||
#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6
|
||||
#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
|
||||
#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8
|
||||
#define USB_OTG_DESCRIPTOR_TYPE 9
|
||||
#define USB_DEBUG_DESCRIPTOR_TYPE 10
|
||||
#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 11
|
||||
|
||||
/* USB Device Classes */
|
||||
#define USB_DEVICE_CLASS_RESERVED 0x00
|
||||
#define USB_DEVICE_CLASS_AUDIO 0x01
|
||||
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
|
||||
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
|
||||
#define USB_DEVICE_CLASS_MONITOR 0x04
|
||||
#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
|
||||
#define USB_DEVICE_CLASS_POWER 0x06
|
||||
#define USB_DEVICE_CLASS_PRINTER 0x07
|
||||
#define USB_DEVICE_CLASS_STORAGE 0x08
|
||||
#define USB_DEVICE_CLASS_HUB 0x09
|
||||
#define USB_DEVICE_CLASS_MISCELLANEOUS 0xEF
|
||||
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
|
||||
|
||||
/* bmAttributes in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWERED_MASK 0x40
|
||||
#define USB_CONFIG_BUS_POWERED 0x80
|
||||
#define USB_CONFIG_SELF_POWERED 0xC0
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x20
|
||||
|
||||
/* bMaxPower in Configuration Descriptor */
|
||||
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
|
||||
|
||||
/* bEndpointAddress in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_DIRECTION_MASK 0x80
|
||||
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
|
||||
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
|
||||
|
||||
/* bmAttributes in Endpoint Descriptor */
|
||||
#define USB_ENDPOINT_TYPE_MASK 0x03
|
||||
#define USB_ENDPOINT_TYPE_CONTROL 0x00
|
||||
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
|
||||
#define USB_ENDPOINT_TYPE_BULK 0x02
|
||||
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
|
||||
#define USB_ENDPOINT_SYNC_MASK 0x0C
|
||||
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
|
||||
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
|
||||
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
|
||||
#define USB_ENDPOINT_USAGE_MASK 0x30
|
||||
#define USB_ENDPOINT_USAGE_DATA 0x00
|
||||
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
|
||||
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
|
||||
#define USB_ENDPOINT_USAGE_RESERVED 0x30
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
typedef struct _USB_DEVICE_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} __attribute__ ((packed)) USB_DEVICE_DESCRIPTOR;
|
||||
|
||||
/* USB 2.0 Device Qualifier Descriptor */
|
||||
typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint8_t bNumConfigurations;
|
||||
uint8_t bReserved;
|
||||
} __attribute__ ((packed)) USB_DEVICE_QUALIFIER_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Configuration Descriptor */
|
||||
typedef struct _USB_CONFIGURATION_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} __attribute__ ((packed)) USB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Interface Descriptor */
|
||||
typedef struct _USB_INTERFACE_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} __attribute__ ((packed)) USB_INTERFACE_DESCRIPTOR;
|
||||
|
||||
/* USB Standard Endpoint Descriptor */
|
||||
typedef struct _USB_ENDPOINT_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
} __attribute__ ((packed)) USB_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
/* USB String Descriptor */
|
||||
typedef struct _USB_STRING_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bString/*[]*/;
|
||||
} __attribute__ ((packed)) USB_STRING_DESCRIPTOR;
|
||||
|
||||
/* USB Common Descriptor */
|
||||
typedef struct _USB_COMMON_DESCRIPTOR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
} __attribute__ ((packed)) USB_COMMON_DESCRIPTOR;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file usbconfig.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "usb.h"
|
||||
#include "usbconfig.h"
|
||||
|
||||
#ifndef WBVAL
|
||||
#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
||||
#endif
|
||||
|
||||
/* USB String Descriptor (optional) */
|
||||
const uint8_t USB_HIDStringDescriptor[] =
|
||||
{
|
||||
/* Index 0x00: LANGID Codes */
|
||||
0x04, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
WBVAL(0x0409), /* US English */ /* wLANGID */
|
||||
/* Index 0x04: Manufacturer */
|
||||
0x1C, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'm',0,
|
||||
'i',0,
|
||||
'c',0,
|
||||
'r',0,
|
||||
'o',0,
|
||||
'B',0,
|
||||
'u',0,
|
||||
'i',0,
|
||||
'l',0,
|
||||
'd',0,
|
||||
'e',0,
|
||||
'r',0,
|
||||
' ',0,
|
||||
/* Index 0x20: Product */
|
||||
0x28, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'L',0,
|
||||
'P',0,
|
||||
'C',0,
|
||||
'1',0,
|
||||
'3',0,
|
||||
'4',0,
|
||||
'3',0,
|
||||
' ',0,
|
||||
'R',0,
|
||||
'e',0,
|
||||
'f',0,
|
||||
'.',0,
|
||||
' ',0,
|
||||
'B',0,
|
||||
'o',0,
|
||||
'a',0,
|
||||
'r',0,
|
||||
'd',0,
|
||||
' ',0,
|
||||
/* Index 0x48: Serial Number */
|
||||
0x1A, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
'0',0,
|
||||
/* Index 0x62: Interface 0, Alternate Setting 0 */
|
||||
0x0E, /* bLength */
|
||||
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
'H',0,
|
||||
'I',0,
|
||||
'D',0,
|
||||
' ',0,
|
||||
' ',0,
|
||||
' ',0,
|
||||
};
|
|
@ -0,0 +1,66 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file usbconfig.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _USBCONFIG_H_
|
||||
#define _USBCONFIG_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
#define USB_VENDOR_ID CFG_USB_VID // Vendor ID
|
||||
#define USB_PROD_ID CFG_USB_PID // Product ID
|
||||
#define USB_DEVICE 0x0100 // Device ID
|
||||
|
||||
#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR))
|
||||
#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
|
||||
#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR))
|
||||
#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR))
|
||||
|
||||
#define HID_DESC_OFFSET 0x0012
|
||||
#define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR))
|
||||
#define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor))
|
||||
|
||||
extern const uint8_t USB_DeviceDescriptor[];
|
||||
extern const uint8_t USB_ConfigDescriptor[];
|
||||
extern const uint8_t USB_HIDStringDescriptor[];
|
||||
|
||||
extern const uint8_t HID_ReportDescriptor[];
|
||||
extern const uint16_t HID_ReportDescSize;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file usbhid.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "core/usbhid-rom/usb.h"
|
||||
#include "core/usbhid-rom/usbconfig.h"
|
||||
#include "core/rom_drivers.h"
|
||||
#include "core/gpio/gpio.h"
|
||||
#include "core/adc/adc.h"
|
||||
#include "core/systick/systick.h"
|
||||
|
||||
#include "usbhid.h"
|
||||
|
||||
USB_DEV_INFO DeviceInfo;
|
||||
HID_DEVICE_INFO HidDevInfo;
|
||||
ROM ** rom = (ROM **)0x1fff1ff8;
|
||||
|
||||
typedef struct usbhid_out_s
|
||||
{
|
||||
uint16_t gpio1Dir;
|
||||
uint16_t gpio1Data;
|
||||
uint16_t gpio2Dir;
|
||||
uint16_t gpio2Data;
|
||||
uint16_t gpio3Dir;
|
||||
uint16_t gpio3Data;
|
||||
uint16_t adc0;
|
||||
uint16_t adc1;
|
||||
uint16_t adc2;
|
||||
uint16_t adc3;
|
||||
uint32_t systicks;
|
||||
uint32_t rollovers;
|
||||
} usbhid_out_t;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the HID In Report (the report going from the LPC1343 to
|
||||
the USB host)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void usbHIDGetInReport (uint8_t src[], uint32_t length)
|
||||
{
|
||||
usbhid_out_t out;
|
||||
|
||||
out.gpio1Dir = GPIO_GPIO1DIR;
|
||||
out.gpio1Data = GPIO_GPIO1DATA;
|
||||
out.gpio2Dir = GPIO_GPIO2DIR;
|
||||
out.gpio2Data = GPIO_GPIO2DATA;
|
||||
out.gpio3Dir = GPIO_GPIO3DIR;
|
||||
out.gpio3Data = GPIO_GPIO3DATA;
|
||||
out.adc0 = adcRead(0);
|
||||
out.adc1 = adcRead(1);
|
||||
out.adc2 = adcRead(2);
|
||||
out.adc3 = adcRead(3);
|
||||
out.systicks = systickGetTicks();
|
||||
out.rollovers = systickGetRollovers();
|
||||
|
||||
size_t i = 0;
|
||||
memcpy(&src[i], &out.gpio1Dir, sizeof out.gpio1Dir);
|
||||
i += sizeof out.gpio1Dir;
|
||||
memcpy(&src[i], &out.gpio1Data, sizeof out.gpio1Data);
|
||||
i += sizeof out.gpio1Data;
|
||||
memcpy(&src[i], &out.gpio2Dir, sizeof out.gpio2Dir);
|
||||
i += sizeof out.gpio2Dir;
|
||||
memcpy(&src[i], &out.gpio2Data, sizeof out.gpio2Data);
|
||||
i += sizeof out.gpio2Data;
|
||||
memcpy(&src[i], &out.gpio3Dir, sizeof out.gpio3Dir);
|
||||
i += sizeof out.gpio3Dir;
|
||||
memcpy(&src[i], &out.gpio3Data, sizeof out.gpio3Data);
|
||||
i += sizeof out.gpio3Data;
|
||||
memcpy(&src[i], &out.adc0, sizeof out.adc0);
|
||||
i += sizeof out.adc0;
|
||||
memcpy(&src[i], &out.adc1, sizeof out.adc1);
|
||||
i += sizeof out.adc1;
|
||||
memcpy(&src[i], &out.adc2, sizeof out.adc2);
|
||||
i += sizeof out.adc2;
|
||||
memcpy(&src[i], &out.adc3, sizeof out.adc3);
|
||||
i += sizeof out.adc3;
|
||||
memcpy(&src[i], &out.systicks, sizeof out.systicks);
|
||||
i += sizeof out.systicks;
|
||||
memcpy(&src[i], &out.rollovers, sizeof out.rollovers);
|
||||
i += sizeof out.rollovers;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the HID Out Report (the report coming in from the USB
|
||||
host to the LPC1343).
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void usbHIDSetOutReport (uint8_t dst[], uint32_t length)
|
||||
{
|
||||
uint8_t PCOutReportData = dst[0];
|
||||
// Check bit 0 in the incoming report to determine is LED should
|
||||
// be enabled or disabled (1 = enabled, 0 = disabled)
|
||||
if (PCOutReportData & (1<<0))
|
||||
{
|
||||
// Enable LED (set low)
|
||||
gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable LED (set high)
|
||||
gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initialises the USB port
|
||||
|
||||
The ROM-based USB HID code is capable of configuring the PLL and pins
|
||||
for USB, but there seems to be a bug in the code that sets the system
|
||||
clock to 48MHz (normally the USB and System clocks can be configured
|
||||
seperately). As such, this code does not use the "init_clk_pins()"
|
||||
function in the rom, and the USB clock and pins are manually
|
||||
configured.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void usbHIDInit (void)
|
||||
{
|
||||
// Setup USB clock
|
||||
SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPAD_PD); // Power-up USB PHY
|
||||
SCB_PDRUNCFG &= ~(SCB_PDSLEEPCFG_USBPLL_PD); // Power-up USB PLL
|
||||
|
||||
SCB_USBPLLCLKSEL = SCB_USBPLLCLKSEL_SOURCE_MAINOSC; // Select PLL Input
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE; // Update Clock Source
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_DISABLE; // Toggle Update Register
|
||||
SCB_USBPLLCLKUEN = SCB_USBPLLCLKUEN_UPDATE;
|
||||
|
||||
// Wait until the USB clock is updated
|
||||
while (!(SCB_USBPLLCLKUEN & SCB_USBPLLCLKUEN_UPDATE));
|
||||
|
||||
// Set USB clock to 48MHz (12MHz x 4)
|
||||
SCB_USBPLLCTRL = (SCB_USBPLLCTRL_MULT_4);
|
||||
while (!(SCB_USBPLLSTAT & SCB_USBPLLSTAT_LOCK)); // Wait Until PLL Locked
|
||||
SCB_USBCLKSEL = SCB_USBCLKSEL_SOURCE_USBPLLOUT;
|
||||
|
||||
// Set USB pin functions
|
||||
IOCON_PIO0_1 &= ~IOCON_PIO0_1_FUNC_MASK;
|
||||
IOCON_PIO0_1 |= IOCON_PIO0_1_FUNC_CLKOUT; // CLK OUT
|
||||
IOCON_PIO0_3 &= ~IOCON_PIO0_3_FUNC_MASK;
|
||||
IOCON_PIO0_3 |= IOCON_PIO0_3_FUNC_USB_VBUS; // VBus
|
||||
IOCON_PIO0_6 &= ~IOCON_PIO0_6_FUNC_MASK;
|
||||
IOCON_PIO0_6 |= IOCON_PIO0_6_FUNC_USB_CONNECT; // Soft Connect
|
||||
|
||||
// Disable internal resistor on VBUS (0.3)
|
||||
gpioSetPullup(&IOCON_PIO0_3, gpioPullupMode_Inactive);
|
||||
|
||||
// HID Device Info
|
||||
volatile int n;
|
||||
HidDevInfo.idVendor = USB_VENDOR_ID;
|
||||
HidDevInfo.idProduct = USB_PROD_ID;
|
||||
HidDevInfo.bcdDevice = USB_DEVICE;
|
||||
HidDevInfo.StrDescPtr = (uint32_t)&USB_HIDStringDescriptor[0];
|
||||
HidDevInfo.InReportCount = sizeof(usbhid_out_t);
|
||||
HidDevInfo.OutReportCount = 1;
|
||||
HidDevInfo.SampleInterval = 0x20;
|
||||
HidDevInfo.InReport = usbHIDGetInReport;
|
||||
HidDevInfo.OutReport = usbHIDSetOutReport;
|
||||
|
||||
DeviceInfo.DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE;
|
||||
DeviceInfo.DevDetailPtr = (uint32_t)&HidDevInfo;
|
||||
|
||||
/* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */
|
||||
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B1 | SCB_SYSAHBCLKCTRL_IOCON | SCB_SYSAHBCLKCTRL_USB_REG);
|
||||
|
||||
/* Use pll and pin init function in rom */
|
||||
/* Warning: This will also set the system clock to 48MHz! */
|
||||
// (*rom)->pUSBD->init_clk_pins();
|
||||
|
||||
/* insert a delay between clk init and usb init */
|
||||
for (n = 0; n < 75; n++) {__asm("nop");}
|
||||
|
||||
(*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */
|
||||
(*rom)->pUSBD->connect(true); /* USB Connect */
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Passes the USB interrupt to the internal ROM-based handler
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#ifdef CFG_USBHID
|
||||
void USB_IRQHandler()
|
||||
{
|
||||
(*rom)->pUSBD->isr();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file usbhid.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _USBCONFIG_H_
|
||||
#define _USBCONFIG_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
void usbHIDGetInReport (uint8_t src[], uint32_t length);
|
||||
void usbHIDSetOutReport (uint8_t dst[], uint32_t length);
|
||||
void usbHIDInit (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file wdt.c
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Sets up the watchdog timer (WDT). The WDT allows you to monitor
|
||||
whether the device is still executing properly. If the watchdog
|
||||
isn't 'fed' within a pre-determined delay, it will raise an interrupt
|
||||
allowing you to decide if you want to reset the device, etc.
|
||||
|
||||
@code
|
||||
#include "core/cpu/cpu.h"
|
||||
#include "core/wdt/wdt.h"
|
||||
...
|
||||
cpuInit();
|
||||
|
||||
// Initialise wdt with no reset on timeout
|
||||
wdtInit(false);
|
||||
|
||||
// Pat the watchdog (to start the timer)
|
||||
wdtFeed();
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Keep the watchdog happy by regularly feeding it
|
||||
wdtFeed();
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#include "wdt.h"
|
||||
|
||||
#define WDT_FEED_VALUE (0x003FFFFF)
|
||||
|
||||
volatile uint32_t wdt_counter;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
IRQ Handler when the watchdog times out. Any actions that you wish
|
||||
to take when a timeout occurs should be called from here.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WDT_IRQHandler(void)
|
||||
{
|
||||
/* Clear the time-out interrupt flag */
|
||||
WDT_WDMOD &= ~WDT_WDMOD_WDTOF;
|
||||
wdt_counter++;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Setup the clock for the watchdog timer. The default setting is 250kHz.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
static void wdtClockSetup (void)
|
||||
{
|
||||
/* Watchdog Configuration */
|
||||
/* Freq. = 0.5MHz, div = 2: WDT_OSC = 250kHz */
|
||||
SCB_WDTOSCCTRL = SCB_WDTOSCCTRL_FREQSEL_0_5MHZ |
|
||||
SCB_WDTOSCCTRL_DIVSEL_DIV2;
|
||||
|
||||
/* Set clock source (use WDT oscillator) */
|
||||
SCB_WDTCLKSEL = SCB_WDTCLKSEL_SOURCE_WATCHDOGOSC;
|
||||
SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE;
|
||||
SCB_WDTCLKUEN = SCB_WDTCLKUEN_DISABLE;
|
||||
SCB_WDTCLKUEN = SCB_WDTCLKUEN_UPDATE;
|
||||
|
||||
/* Wait until updated */
|
||||
while (!(SCB_WDTCLKUEN & SCB_WDTCLKUEN_UPDATE));
|
||||
|
||||
/* Set divider */
|
||||
SCB_WDTCLKDIV = SCB_WDTCLKDIV_DIV1;
|
||||
|
||||
/* Enable WDT clock */
|
||||
SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_WDTOSC);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Initialises the watchdog timer and sets up the interrupt.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void wdtInit (bool reset)
|
||||
{
|
||||
/* Setup the WDT clock */
|
||||
wdtClockSetup();
|
||||
|
||||
/* Enable AHB clock to the WDT domain. */
|
||||
SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_WDT;
|
||||
|
||||
wdt_counter = 0;
|
||||
|
||||
/* Enable the WDT interrupt */
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
|
||||
/* Set timeout value (must be at least 0x000000FF) */
|
||||
WDT_WDTC = WDT_FEED_VALUE;
|
||||
|
||||
/* Enable the watchdog timer (without system reset) */
|
||||
WDT_WDMOD = WDT_WDMOD_WDEN_ENABLED |
|
||||
reset ? WDT_WDMOD_WDRESET_ENABLED : WDT_WDMOD_WDRESET_DISABLED ;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Feeds the watchdog to keep it from timing out. Interrupts will be
|
||||
disabled while feeding the watchdog.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void wdtFeed (void)
|
||||
{
|
||||
/* Pet the watchdog */
|
||||
__disable_irq();
|
||||
WDT_WDFEED = WDT_WDFEED_FEED1;
|
||||
WDT_WDFEED = WDT_WDFEED_FEED2;
|
||||
__enable_irq();
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file wdt.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _WDT_H_
|
||||
#define _WDT_H_
|
||||
|
||||
#include "projectconfig.h"
|
||||
|
||||
void wdtInit (bool reset);
|
||||
void wdtFeed (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// The GCC compiler defines the current architecture derived from the -mcpu argument.
|
||||
// When target cpu is the cortex-m0, it automatically defines __ARM_ARCH_6M__
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#error "The target ARM cpu must be Cortex-M0 compatible (-mcpu=cortex-m0)"
|
||||
#endif
|
||||
|
||||
// Declare a weak alias macro as described in the GCC manual[1][2]
|
||||
#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f)));
|
||||
#define SECTION(s) __attribute__ ((section(s)))
|
||||
|
||||
/******************************************************************************
|
||||
* Forward undefined IRQ handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
*****************************************************************************/
|
||||
|
||||
void irq_undefined() {
|
||||
// Do nothing when occured interrupt is not defined, just keep looping
|
||||
while(1);
|
||||
}
|
||||
|
||||
void CAN_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void SSP1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void SSP0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
|
||||
/*****************************************************************************
|
||||
* Forward undefined fault handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
****************************************************************************/
|
||||
|
||||
void fault_undefined() {
|
||||
// Do nothing when occured interrupt is not defined, just keep looping
|
||||
while(1);
|
||||
}
|
||||
|
||||
void NMI_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void HardFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void MemManage_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void BusFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void SVCall_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void PendSV_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void SysTick_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
|
||||
/******************************************************************************
|
||||
* Forward undefined IRQ handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
*****************************************************************************/
|
||||
|
||||
// Prototype the entry values, which are handled by the linker script
|
||||
extern void* stack_entry;
|
||||
extern void boot_entry(void);
|
||||
|
||||
// Defined irq vectors using simple c code following the description in a white
|
||||
// paper from ARM[3] and code example from Simonsson Fun Technologies[4].
|
||||
// These vectors are placed at the memory location defined in the linker script
|
||||
const void *vectors[] SECTION(".irq_vectors") =
|
||||
{
|
||||
// Stack and program reset entry point
|
||||
&stack_entry, // The initial stack pointer
|
||||
boot_entry, // The reset handler
|
||||
|
||||
// Various fault handlers
|
||||
NMI_Handler, // The NMI handler
|
||||
HardFault_Handler, // The hard fault handler
|
||||
MemManage_Handler, // MemManage_Handler
|
||||
BusFault_Handler, // BusFault_Handler
|
||||
UsageFault_Handler, // UsageFault_Handler
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
SVCall_Handler, // SVCall handler
|
||||
DebugMon_Handler, // DebugMon_Handler
|
||||
0, // Reserved
|
||||
PendSV_Handler, // The PendSV handler
|
||||
SysTick_Handler, // The SysTick handler
|
||||
|
||||
// Wakeup I/O pins handlers
|
||||
WAKEUP_IRQHandler, // PIO0_0 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_1 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_2 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_3 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_4 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_5 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_6 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_7 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_8 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_9 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_10 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_11 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_0 Wakeup
|
||||
|
||||
// Specific peripheral irq handlers
|
||||
CAN_IRQHandler, // CAN
|
||||
SSP1_IRQHandler, // SSP1
|
||||
I2C_IRQHandler, // I2C0
|
||||
TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0)
|
||||
TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1)
|
||||
TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0)
|
||||
TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1)
|
||||
SSP0_IRQHandler, // SSP0
|
||||
UART_IRQHandler, // UART0
|
||||
USB_IRQHandler, // USB IRQ
|
||||
USB_FIQHandler, // USB FIQ
|
||||
ADC_IRQHandler, // ADC (A/D Converter)
|
||||
WDT_IRQHandler, // WDT (Watchdog Timer)
|
||||
BOD_IRQHandler, // BOD (Brownout Detect)
|
||||
FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller)
|
||||
PIOINT3_IRQHandler, // PIO INT3
|
||||
PIOINT2_IRQHandler, // PIO INT2
|
||||
PIOINT1_IRQHandler, // PIO INT1
|
||||
PIOINT0_IRQHandler, // PIO INT0
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* References
|
||||
* [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
|
||||
* [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
|
||||
* [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf
|
||||
* [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php
|
||||
*****************************************************************************/
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// The GCC compiler defines the current architecture derived from the -mcpu argument.
|
||||
// When target cpu is the cortex-m3, it automatically defines __ARM_ARCH_7M__
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#error "The target ARM cpu must be Cortex-M3 compatible (-mcpu=cortex-m3)"
|
||||
#endif
|
||||
|
||||
// Declare a weak alias macro as described in the GCC manual[1][2]
|
||||
#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f)));
|
||||
#define SECTION(s) __attribute__ ((section(s)))
|
||||
|
||||
/******************************************************************************
|
||||
* Forward undefined IRQ handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
*****************************************************************************/
|
||||
|
||||
void irq_undefined() {
|
||||
// Do nothing when occured interrupt is not defined, just keep looping
|
||||
while(1);
|
||||
}
|
||||
|
||||
void I2C_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER16_0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER16_1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER32_0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void TIMER32_1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void SSP_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void UART_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void USB_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void USB_FIQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void ADC_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void WDT_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void BOD_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void FMC_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT3_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT2_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT1_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void PIOINT0_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
void WAKEUP_IRQHandler(void) WEAK_ALIAS(irq_undefined);
|
||||
|
||||
/*****************************************************************************
|
||||
* Forward undefined fault handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
****************************************************************************/
|
||||
|
||||
void fault_undefined() {
|
||||
// Do nothing when occured interrupt is not defined, just keep looping
|
||||
while(1);
|
||||
}
|
||||
|
||||
void NMI_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void HardFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void MemManage_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void BusFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void UsageFault_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void SVCall_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void DebugMon_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void PendSV_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
void SysTick_Handler(void) WEAK_ALIAS(fault_undefined);
|
||||
|
||||
/******************************************************************************
|
||||
* Forward undefined IRQ handlers to an infinite loop function. The Handlers
|
||||
* are weakly aliased which means that (re)definitions will overide these.
|
||||
*****************************************************************************/
|
||||
|
||||
// Prototype the entry values, which are handled by the linker script
|
||||
extern void* stack_entry;
|
||||
extern void boot_entry(void);
|
||||
|
||||
// Defined irq vectors using simple c code following the description in a white
|
||||
// paper from ARM[3] and code example from Simonsson Fun Technologies[4].
|
||||
// These vectors are placed at the memory location defined in the linker script
|
||||
const void *vectors[] SECTION(".irq_vectors") =
|
||||
{
|
||||
// Stack and program reset entry point
|
||||
&stack_entry, // The initial stack pointer
|
||||
boot_entry, // The reset handler
|
||||
|
||||
// Various fault handlers
|
||||
NMI_Handler, // The NMI handler
|
||||
HardFault_Handler, // The hard fault handler
|
||||
MemManage_Handler, // The MPU fault handler
|
||||
BusFault_Handler, // The bus fault handler
|
||||
UsageFault_Handler, // The usage fault handler
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
SVCall_Handler, // SVCall handler
|
||||
DebugMon_Handler, // Debug monitor handler
|
||||
0, // Reserved
|
||||
PendSV_Handler, // The PendSV handler
|
||||
SysTick_Handler, // The SysTick handler
|
||||
|
||||
// Wakeup I/O pins handlers
|
||||
WAKEUP_IRQHandler, // PIO0_0 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_1 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_2 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_3 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_4 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_5 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_6 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_7 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_8 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_9 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_10 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO0_11 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_0 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_1 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_2 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_3 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_4 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_5 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_6 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_7 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_8 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_9 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_10 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO1_11 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_0 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_1 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_2 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_3 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_4 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_5 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_6 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_7 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_8 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_9 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_10 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO2_11 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO3_0 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO3_1 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO3_2 Wakeup
|
||||
WAKEUP_IRQHandler, // PIO3_3 Wakeup
|
||||
|
||||
// Specific peripheral irq handlers
|
||||
I2C_IRQHandler, // I2C0
|
||||
TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0)
|
||||
TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1)
|
||||
TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0)
|
||||
TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1)
|
||||
SSP_IRQHandler, // SSP0
|
||||
UART_IRQHandler, // UART0
|
||||
USB_IRQHandler, // USB IRQ
|
||||
USB_FIQHandler, // USB FIQ
|
||||
ADC_IRQHandler, // ADC (A/D Converter)
|
||||
WDT_IRQHandler, // WDT (Watchdog Timer)
|
||||
BOD_IRQHandler, // BOD (Brownout Detect)
|
||||
FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller)
|
||||
PIOINT3_IRQHandler, // PIO INT3
|
||||
PIOINT2_IRQHandler, // PIO INT2
|
||||
PIOINT1_IRQHandler, // PIO INT1
|
||||
PIOINT0_IRQHandler, // PIO INT0
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* References
|
||||
* [1] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
|
||||
* [2] http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
|
||||
* [3] http://www.arm.com/files/pdf/Cortex-M3_programming_for_ARM7_developers.pdf
|
||||
* [4] http://fun-tech.se/stm32/OlimexBlinky/mini.php
|
||||
*****************************************************************************/
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// These are defined and created by the linker, locating them in memory
|
||||
extern unsigned char _etext;
|
||||
extern unsigned char _data;
|
||||
extern unsigned char _edata;
|
||||
extern unsigned char _bss;
|
||||
extern unsigned char _ebss;
|
||||
|
||||
// Prototype the required startup functions
|
||||
extern void main(void);
|
||||
|
||||
// The entry point of the application, prepare segments,
|
||||
// initialize the cpu and execute main()
|
||||
void boot_entry(void)
|
||||
{
|
||||
register unsigned char *src, *dst;
|
||||
|
||||
// Get physical data address and copy it to sram
|
||||
src = &_etext;
|
||||
dst = &_data;
|
||||
while(dst < &_edata) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
// Clear the bss segment
|
||||
dst = &_bss;
|
||||
while(dst < &_ebss) {
|
||||
*dst++ = 0;
|
||||
}
|
||||
|
||||
// Execute the code at the program entry point
|
||||
main();
|
||||
|
||||
// Do nothing when returned from main, just keep looping
|
||||
while(1);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
sram_top = ORIGIN(sram) + LENGTH(sram);
|
||||
ENTRY(boot_entry)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.irq_vectors))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
} > flash
|
||||
|
||||
/*
|
||||
* More information about Special Section Indexes is available in the
|
||||
* free "ELF for the ARM Architecture" document from ARM Limited
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
|
||||
*
|
||||
*/
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > flash
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > flash
|
||||
__exidx_end = .;
|
||||
|
||||
_etext = .;
|
||||
|
||||
.data : AT (__exidx_end)
|
||||
{
|
||||
_data = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
/* zero initialized data */
|
||||
.bss :
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_ebss = .;
|
||||
} > sram
|
||||
|
||||
end = .;
|
||||
|
||||
/* For GDB compatibility we decrease the top with 16 bytes */
|
||||
stack_entry = sram_top - 16;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file sysdefs.h
|
||||
@author K. Townsend (microBuilder.eu)
|
||||
@date 22 March 2010
|
||||
@version 0.10
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, microBuilder SARL
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef _SYSDEFS_H_
|
||||
#define _SYSDEFS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Stay compatible with ugly "windows" style
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
typedef volatile uint8_t REG8;
|
||||
typedef volatile uint16_t REG16;
|
||||
typedef volatile uint32_t REG32;
|
||||
typedef unsigned char byte_t;
|
||||
|
||||
#define pREG8 (REG8 *)
|
||||
#define pREG16 (REG16 *)
|
||||
#define pREG32 (REG32 *)
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
CC = gcc
|
||||
LD = gcc
|
||||
LDFLAGS = -Wall -O4 -std=c99
|
||||
EXES = lpcrc
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
% : %.c
|
||||
$(LD) $(LDFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(EXES)
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Software License Agreement (BSD License)
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BLOCK_COUNT 7
|
||||
#define BLOCK_LENGTH 4
|
||||
#define BLOCK_TOTAL (BLOCK_COUNT*BLOCK_LENGTH)
|
||||
|
||||
typedef unsigned char byte_t;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE* pf;
|
||||
byte_t buf[BLOCK_TOTAL];
|
||||
uint32_t crc = 0;
|
||||
uint32_t block;
|
||||
|
||||
// Check for required arguments
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("syntax: lpcrc <firmware.bin>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Try to open the supplied firmware
|
||||
if ((pf = fopen(argv[1],"rb+")) == NULL)
|
||||
{
|
||||
printf("error: could not open file [%s] with write access\n",argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read out the data blocks used for crc calculation
|
||||
if (fread(buf,1,BLOCK_TOTAL,pf) != BLOCK_TOTAL)
|
||||
{
|
||||
printf("error: could not read required bytes\n");
|
||||
fclose(pf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Compute the crc value
|
||||
for (block=0; block<BLOCK_COUNT; block++)
|
||||
{
|
||||
crc += *((uint32_t*)(buf+(block*BLOCK_LENGTH)));
|
||||
}
|
||||
crc = (~crc) + 1;
|
||||
|
||||
// Reposition the file stream indicator to switch between read and write
|
||||
if (fseek(pf,0,SEEK_CUR) != 0)
|
||||
{
|
||||
printf("error: could not switch from read to write mode\n");
|
||||
fclose(pf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Write the crc back to the file
|
||||
if (fwrite((byte_t*)&crc,1,BLOCK_LENGTH,pf) != BLOCK_LENGTH)
|
||||
{
|
||||
printf("error: could not write crc back to file\n");
|
||||
fclose(pf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("succesfully updated crc to: %08x\n",crc);
|
||||
fclose(pf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue