Compare commits
37 Commits
master
...
mci-rewrit
Author | SHA1 | Date |
---|---|---|
Dimitri Stolnikov | 562b31a64e | |
Dimitri Stolnikov | b697821a8d | |
Hoernchen | 0e00ac4663 | |
Christian Daniel | 159bd582a4 | |
Christian Daniel | 43e6448d0c | |
Christian Daniel | d0360315b3 | |
Christian Daniel | 4ec94b60bd | |
Christian Daniel | fc74cd8ce9 | |
Christian Daniel | 0e7bfc6097 | |
Christian Daniel | 41184d6706 | |
Christian Daniel | 6b77966f35 | |
Christian Daniel | 559a3b1e90 | |
Christian Daniel | ba4ebda883 | |
Christian Daniel | a2883095ed | |
Christian Daniel | 3088cd904e | |
Christian Daniel | 8c60ae3746 | |
Christian Daniel | 08ac2f7e4c | |
Christian Daniel | b4c4d46fb1 | |
Christian Daniel | 5ee4d33c02 | |
Christian Daniel | c0383b32a3 | |
Hoernchen | 4349afe1f6 | |
Christian Vogel | ffec059aeb | |
Christian Daniel | a5a3280178 | |
Christian Daniel | 4952c3f05e | |
Christian Daniel | f632a7b7b8 | |
Christian Daniel | b4e144f150 | |
Christian Daniel | bc917000f5 | |
Christian Daniel | cc2fc0e5b6 | |
Christian Daniel | 8d91910f74 | |
Christian Daniel | ed0d85cf33 | |
Christian Daniel | e26ecd5227 | |
Christian Daniel | 48311dbf93 | |
Christian Daniel | d5a6df3a4d | |
Christian Daniel | a697e6afe2 | |
Christian Daniel | f077a9c4cb | |
Christian Daniel | 7cbe4b852e | |
Christian Daniel | b17fd2ca39 |
|
@ -0,0 +1,77 @@
|
|||
Most of this code was originally written by Harald Welte, who used this
|
||||
license text:
|
||||
|
||||
/* (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
Some files were taken from Atmel reference code, which contains the following
|
||||
copyright statement:
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
We also borrowed a bit from the Linux kernel - printf and folks:
|
||||
|
||||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
Also we use the ARM CMIS library:
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 15. February 2012
|
||||
* $Revision: V1.1.0
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* ----------------------------------------------------------------------*/
|
||||
|
||||
For all other files, the author is named in the header of the file.
|
|
@ -0,0 +1,143 @@
|
|||
# binary file name
|
||||
TARGET=dfuapp
|
||||
|
||||
CROSS_COMPILE=arm-none-eabi-
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)gcc
|
||||
OBJCOPY=$(CROSS_COMPILE)objcopy
|
||||
OBJDUMP=$(CROSS_COMPILE)objdump
|
||||
BUILDDIR=build
|
||||
OBJDIR=$(BUILDDIR)/obj
|
||||
DEPDIR=$(BUILDDIR)/dep
|
||||
|
||||
RUMBA=rumba
|
||||
RUMBA_TTY=/dev/ttyACM0
|
||||
|
||||
# prevent make from displaying full command lines
|
||||
QUIET=@
|
||||
|
||||
C_SOURCES=\
|
||||
main.c \
|
||||
startup.c \
|
||||
vectors.c \
|
||||
\
|
||||
at91sam3u4/core_cm3.c \
|
||||
\
|
||||
crt/printf.c \
|
||||
crt/sprintf.c \
|
||||
crt/stdio.c \
|
||||
crt/vsprintf.c \
|
||||
crt/vprintf.c \
|
||||
\
|
||||
driver/dbgio.c \
|
||||
driver/flash.c \
|
||||
driver/led.c \
|
||||
driver/irq.c \
|
||||
driver/sys.c \
|
||||
driver/usbdhs.c \
|
||||
\
|
||||
usb/descriptors.c \
|
||||
usb/hardware.c \
|
||||
usb/usb.c \
|
||||
usb/usbdevice.c \
|
||||
usb/slimpro.c
|
||||
|
||||
all: build
|
||||
|
||||
# general compiler flags
|
||||
CFLAGS=\
|
||||
-mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -fdata-sections -std=gnu99 \
|
||||
-Os -g3 -Wall -Dat91sam3u4 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fno-builtin-vsprintf \
|
||||
-fno-builtin-vprintf \
|
||||
-fno-builtin-puts \
|
||||
-fno-builtin-printf \
|
||||
-Wimplicit
|
||||
LDFLAGS=-g3 -Wl,-Map=$(BUILDDIR)/$(TARGET).map -nostdlib -nostartfiles -mcpu=cortex-m3 -mthumb -Wl,--gc-sections -T"src/at91sam3u4/flash.lds"
|
||||
LIBS=
|
||||
|
||||
##############################################################################
|
||||
|
||||
SUBDIRS=$(sort $(dir $(C_SOURCES)))
|
||||
|
||||
DEPDIRS=$(addprefix $(DEPDIR)/,$(SUBDIRS))
|
||||
OBJDIRS=$(addprefix $(OBJDIR)/,$(SUBDIRS))
|
||||
|
||||
COBJS=$(addprefix $(OBJDIR)/,$(C_SOURCES:%.c=%.o))
|
||||
DEPS=$(C_SOURCES:%.c=%.dep)
|
||||
FULLDEPS=$(addprefix $(DEPDIR)/,$(DEPS))
|
||||
|
||||
BUILD_DATE=$(shell date "+%Y-%m-%d")
|
||||
BUILD_TIME=$(shell date "+%H:%M:%S")
|
||||
BUILD_ZONE=$(shell date "+%Z")
|
||||
BUILD_HOST=$(shell uname -n)
|
||||
BUILD_GCC=$(shell $(CC) --version | head -1)
|
||||
BUILD_VCSID=$(shell ../../git-version-gen ../../.tarball_version)
|
||||
|
||||
.PHONY: all build buildid clean distclean flash dfuflash
|
||||
|
||||
build: $(OBJDIRS) $(DEPDIRS) buildid $(BUILDDIR)/$(TARGET).bin $(BUILDDIR)/$(TARGET).asm
|
||||
|
||||
buildid: $(OBJDIRS)
|
||||
@echo [GEN]\ $(BUILDDIR)/buildid.h
|
||||
$(QUIET)echo -en \
|
||||
"#ifndef INCLUDE_BUILDID_H\n"\
|
||||
"#define INCLUDE_BUILDID_H\n"\
|
||||
"\n"\
|
||||
"#define BUILDID_DATE \"$(BUILD_DATE)\"\n"\
|
||||
"#define BUILDID_TIME \"$(BUILD_TIME)\"\n"\
|
||||
"#define BUILDID_ZONE \"$(BUILD_ZONE)\"\n"\
|
||||
"#define BUILDID_HOST \"$(BUILD_HOST)\"\n"\
|
||||
"#define BUILDID_GCC \"$(BUILD_GCC)\"\n"\
|
||||
"#define BUILDID_VCSID \"$(BUILD_VCSID)\"\n"\
|
||||
"\n"\
|
||||
"#endif // INCLUDE_BUILDID_H\n"\
|
||||
> $(BUILDDIR)/buildid.h
|
||||
|
||||
-include $(FULLDEPS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET).bin: $(BUILDDIR)/$(TARGET).elf
|
||||
@echo [BIN] $@
|
||||
$(QUIET)$(OBJCOPY) \
|
||||
-O binary $(BUILDDIR)/$(TARGET).elf $(BUILDDIR)/$(TARGET).bin
|
||||
$(QUIET)ls -la $@ | awk '{ print " image has", $$5, "bytes"; }'
|
||||
|
||||
$(BUILDDIR)/$(TARGET).asm: $(BUILDDIR)/$(TARGET).elf
|
||||
@echo [ASM] $@
|
||||
$(QUIET)$(OBJDUMP) \
|
||||
-deS --disassembler-options=force-thumb $(BUILDDIR)/$(TARGET).elf > $(BUILDDIR)/$(TARGET).asm
|
||||
|
||||
$(BUILDDIR)/$(TARGET).elf: $(COBJS)
|
||||
@echo [LD\ ]\ $@
|
||||
$(QUIET)$(LD) \
|
||||
$(LDFLAGS) \
|
||||
-o $(BUILDDIR)/$(TARGET).elf \
|
||||
-Wl,--start-group $(COBJS) $(LIBS) -Wl,--end-group
|
||||
|
||||
$(COBJS):
|
||||
@echo [C\ \ ]\ $(patsubst %.o,%.c,$(patsubst $(OBJDIR)/%,%,$@))
|
||||
$(QUIET)$(CC) \
|
||||
$(CFLAGS) \
|
||||
$(CFLAGS_$(subst /,_,$(patsubst %.o,%,$(patsubst $(OBJDIR)/%,%,$@)))) \
|
||||
-MD -MP -MF $(patsubst %.o,$(DEPDIR)/%.dep,$(patsubst $(OBJDIR)/%,%,$@)) \
|
||||
-c src/$(patsubst %.o,%.c,$(patsubst $(OBJDIR)/%,%,$@)) \
|
||||
-o $@
|
||||
|
||||
$(OBJDIRS) $(DEPDIRS) $(GENERATED):
|
||||
$(QUIET)mkdir -p $@
|
||||
|
||||
clean:
|
||||
@echo [CLEAN]
|
||||
$(QUIET)rm -Rf $(OBJDIR) $(DEPDIR) $(BUILDDIR)/buildid.h
|
||||
|
||||
distclean:
|
||||
@echo [DISTCLEAN]
|
||||
$(QUIET)rm -Rf $(BUILDDIR)
|
||||
|
||||
flash: build
|
||||
$(QUIET)$(RUMBA) $(RUMBA_TTY) flashmcu $(BUILDDIR)/$(TARGET).bin
|
||||
|
||||
dfuflash: build
|
||||
$(QUIET)sudo dfu-util -d 16c0:0763 -a 1 -D $(BUILDDIR)/$(TARGET).bin -R
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,140 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \unit
|
||||
/// !Purpose
|
||||
///
|
||||
/// Definition of AT91SAM3U4 characteristics and features
|
||||
///
|
||||
/// !Usage
|
||||
/// -# For ARM core feature, see "AT91SAM3U4 - ARM core features".
|
||||
/// -# For IP features, see "AT91SAM3U4 - IP features".
|
||||
/// -# For misc, see "AT91SAM3U4 - Misc".
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef CHIP_H
|
||||
#define CHIP_H
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Headers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - ARM core features"
|
||||
/// This page lists several characteristics related to the ARM core
|
||||
///
|
||||
|
||||
//ARM core features
|
||||
|
||||
/// ARM core definition.
|
||||
#define cortexm3
|
||||
|
||||
/// family definition.
|
||||
#define at91sam3u
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - IP features"
|
||||
/// This page lists several characteristics related to the embedded IP
|
||||
///
|
||||
|
||||
//IP FEATURES
|
||||
|
||||
// EFC GPNVM number
|
||||
#define CHIP_EFC_NUM_GPNVMS 3
|
||||
|
||||
/// Indicates chip has an Enhanced EFC.
|
||||
#define CHIP_FLASH_EEFC
|
||||
|
||||
// DMA channels number
|
||||
#define CHIP_DMA_CHANNEL_NUM 4
|
||||
|
||||
// Indicate chip's MCI interface.
|
||||
#define MCI2_INTERFACE
|
||||
|
||||
// Indicate chip has a nandflash controller.
|
||||
#define CHIP_NAND_CTRL
|
||||
|
||||
// Indicate chip SSC has DMA interface.
|
||||
#define CHIP_SSC_DMA
|
||||
|
||||
// Indicate chip SPI has DMA interface.
|
||||
#define CHIP_SPI_DMA
|
||||
|
||||
/// Indicates chip has an UDP High Speed.
|
||||
#define CHIP_USB_UDPHS
|
||||
|
||||
/// Indicates chip has an internal pull-up.
|
||||
#define CHIP_USB_PULLUP_INTERNAL
|
||||
|
||||
/// Number of USB endpoints
|
||||
#define CHIP_USB_NUMENDPOINTS 7
|
||||
|
||||
/// Endpoints max paxcket size
|
||||
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
|
||||
((i == 0) ? 64 : \
|
||||
((i == 1) ? 512 : \
|
||||
((i == 2) ? 512 : \
|
||||
((i == 3) ? 64 : \
|
||||
((i == 4) ? 64 : \
|
||||
((i == 5) ? 1024 : \
|
||||
((i == 6) ? 1024 : 0 )))))))
|
||||
|
||||
/// Endpoints Number of Bank
|
||||
#define CHIP_USB_ENDPOINTS_BANKS(i) \
|
||||
((i == 0) ? 1 : \
|
||||
((i == 1) ? 2 : \
|
||||
((i == 2) ? 2 : \
|
||||
((i == 3) ? 3 : \
|
||||
((i == 4) ? 3 : \
|
||||
((i == 5) ? 3 : \
|
||||
((i == 6) ? 3 : 0 )))))))
|
||||
|
||||
/// Endpoints max paxcket size
|
||||
#define CHIP_USB_ENDPOINTS_DMA(i) \
|
||||
((i == 1) ? 1 : \
|
||||
((i == 2) ? 1 : \
|
||||
((i == 3) ? 1 : \
|
||||
((i == 4) ? 1 : \
|
||||
((i == 5) ? 1 : \
|
||||
((i == 6) ? 1 : 0 ))))))
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - Misc "
|
||||
/// This page lists misc features
|
||||
///
|
||||
|
||||
//Misc
|
||||
|
||||
#endif //#ifndef CHIP_H
|
||||
|
|
@ -0,0 +1,805 @@
|
|||
/******************************************************************************
|
||||
* @file: core_cm3.c
|
||||
* @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Source File
|
||||
* @version: V1.10
|
||||
* @date: 24. Feb. 2009
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2009 ARM Limited. All rights reserved.
|
||||
*
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for armcc */
|
||||
#define __INLINE __inline /*!< inline keyword for armcc */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for iarcc */
|
||||
#define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */
|
||||
#define __nop __no_operation /*!< no operation intrinsic in iarcc */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM asm /*!< asm keyword for gcc */
|
||||
#define __INLINE inline /*!< inline keyword for gcc */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
|
||||
/**
|
||||
* @brief Return the Process Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t ProcessStackPointer
|
||||
*
|
||||
* Return the actual process stack pointer
|
||||
*/
|
||||
__ASM uint32_t __get_PSP(void)
|
||||
{
|
||||
mrs r0, psp
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Process Stack Pointer
|
||||
*
|
||||
* @param uint32_t Process Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value ProcessStackPointer to the MSP
|
||||
* (process stack pointer) Cortex processor register
|
||||
*/
|
||||
__ASM void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
msr psp, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Main Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t Main Stack Pointer
|
||||
*
|
||||
* Return the current value of the MSP (main stack pointer)
|
||||
* Cortex processor register
|
||||
*/
|
||||
__ASM uint32_t __get_MSP(void)
|
||||
{
|
||||
mrs r0, msp
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Main Stack Pointer
|
||||
*
|
||||
* @param uint32_t Main Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value mainStackPointer to the MSP
|
||||
* (main stack pointer) Cortex processor register
|
||||
*/
|
||||
__ASM void __set_MSP(uint32_t mainStackPointer)
|
||||
{
|
||||
msr msp, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in unsigned short value
|
||||
*
|
||||
* @param uint16_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse byte order in unsigned short value
|
||||
*/
|
||||
__ASM uint32_t __REV16(uint16_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in signed short value with sign extension to integer
|
||||
*
|
||||
* @param int16_t value to reverse
|
||||
* @return int32_t reversed value
|
||||
*
|
||||
* Reverse byte order in signed short value with sign extension to integer
|
||||
*/
|
||||
__ASM int32_t __REVSH(int16_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
#if (__ARMCC_VERSION < 400000)
|
||||
|
||||
/**
|
||||
* @brief Remove the exclusive lock created by ldrex
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* Removes the exclusive lock which is created by ldrex.
|
||||
*/
|
||||
__ASM void __CLREX(void)
|
||||
{
|
||||
clrex
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Base Priority value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t BasePriority
|
||||
*
|
||||
* Return the content of the base priority register
|
||||
*/
|
||||
__ASM uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
mrs r0, basepri
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Base Priority value
|
||||
*
|
||||
* @param uint32_t BasePriority
|
||||
* @return none
|
||||
*
|
||||
* Set the base priority register
|
||||
*/
|
||||
__ASM void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
msr basepri, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Priority Mask value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t PriMask
|
||||
*
|
||||
* Return the state of the priority mask bit from the priority mask
|
||||
* register
|
||||
*/
|
||||
__ASM uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
mrs r0, primask
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Priority Mask value
|
||||
*
|
||||
* @param uint32_t PriMask
|
||||
* @return none
|
||||
*
|
||||
* Set the priority mask bit in the priority mask register
|
||||
*/
|
||||
__ASM void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
msr primask, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Fault Mask value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t FaultMask
|
||||
*
|
||||
* Return the content of the fault mask register
|
||||
*/
|
||||
__ASM uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
mrs r0, faultmask
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Fault Mask value
|
||||
*
|
||||
* @param uint32_t faultMask value
|
||||
* @return none
|
||||
*
|
||||
* Set the fault mask register
|
||||
*/
|
||||
__ASM void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
msr faultmask, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Control Register value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t Control value
|
||||
*
|
||||
* Return the content of the control register
|
||||
*/
|
||||
__ASM uint32_t __get_CONTROL(void)
|
||||
{
|
||||
mrs r0, control
|
||||
bx lr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Control Register value
|
||||
*
|
||||
* @param uint32_t Control value
|
||||
* @return none
|
||||
*
|
||||
* Set the control register
|
||||
*/
|
||||
__ASM void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
msr control, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
#endif /* __ARMCC_VERSION */
|
||||
|
||||
|
||||
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
|
||||
#pragma diag_suppress=Pe940
|
||||
|
||||
/**
|
||||
* @brief Return the Process Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t ProcessStackPointer
|
||||
*
|
||||
* Return the actual process stack pointer
|
||||
*/
|
||||
uint32_t __get_PSP(void)
|
||||
{
|
||||
__ASM("mrs r0, psp");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Process Stack Pointer
|
||||
*
|
||||
* @param uint32_t Process Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value ProcessStackPointer to the MSP
|
||||
* (process stack pointer) Cortex processor register
|
||||
*/
|
||||
void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM("msr psp, r0");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Main Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t Main Stack Pointer
|
||||
*
|
||||
* Return the current value of the MSP (main stack pointer)
|
||||
* Cortex processor register
|
||||
*/
|
||||
uint32_t __get_MSP(void)
|
||||
{
|
||||
__ASM("mrs r0, msp");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Main Stack Pointer
|
||||
*
|
||||
* @param uint32_t Main Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value mainStackPointer to the MSP
|
||||
* (main stack pointer) Cortex processor register
|
||||
*/
|
||||
void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM("msr msp, r0");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in unsigned short value
|
||||
*
|
||||
* @param uint16_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse byte order in unsigned short value
|
||||
*/
|
||||
uint32_t __REV16(uint16_t value)
|
||||
{
|
||||
__ASM("rev16 r0, r0");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse bit order of value
|
||||
*
|
||||
* @param uint32_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse bit order of value
|
||||
*/
|
||||
uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
__ASM("rbit r0, r0");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint8_t* address
|
||||
* @return uint8_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint8_t __LDREXB(uint8_t *addr)
|
||||
{
|
||||
__ASM("ldrexb r0, [r0]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint16_t* address
|
||||
* @return uint16_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint16_t __LDREXH(uint16_t *addr)
|
||||
{
|
||||
__ASM("ldrexh r0, [r0]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint32_t* address
|
||||
* @return uint32_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint32_t __LDREXW(uint32_t *addr)
|
||||
{
|
||||
__ASM("ldrex r0, [r0]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint8_t *address
|
||||
* @param uint8_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
||||
{
|
||||
__ASM("strexb r0, r0, [r1]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint16_t *address
|
||||
* @param uint16_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
||||
{
|
||||
__ASM("strexh r0, r0, [r1]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint32_t *address
|
||||
* @param uint32_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXW(uint32_t value, uint32_t *addr)
|
||||
{
|
||||
__ASM("strex r0, r0, [r1]");
|
||||
__ASM("bx lr");
|
||||
}
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
|
||||
|
||||
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
|
||||
|
||||
/**
|
||||
* @brief Return the Process Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t ProcessStackPointer
|
||||
*
|
||||
* Return the actual process stack pointer
|
||||
*/
|
||||
uint32_t __get_PSP(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, psp" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Process Stack Pointer
|
||||
*
|
||||
* @param uint32_t Process Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value ProcessStackPointer to the MSP
|
||||
* (process stack pointer) Cortex processor register
|
||||
*/
|
||||
void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Main Stack Pointer
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t Main Stack Pointer
|
||||
*
|
||||
* Return the current value of the MSP (main stack pointer)
|
||||
* Cortex processor register
|
||||
*/
|
||||
uint32_t __get_MSP(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, msp" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Main Stack Pointer
|
||||
*
|
||||
* @param uint32_t Main Stack Pointer
|
||||
* @return none
|
||||
*
|
||||
* Assign the value mainStackPointer to the MSP
|
||||
* (main stack pointer) Cortex processor register
|
||||
*/
|
||||
void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Base Priority value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t BasePriority
|
||||
*
|
||||
* Return the content of the base priority register
|
||||
*/
|
||||
uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Base Priority value
|
||||
*
|
||||
* @param uint32_t BasePriority
|
||||
* @return none
|
||||
*
|
||||
* Set the base priority register
|
||||
*/
|
||||
void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Priority Mask value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t PriMask
|
||||
*
|
||||
* Return the state of the priority mask bit from the priority mask
|
||||
* register
|
||||
*/
|
||||
uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Priority Mask value
|
||||
*
|
||||
* @param uint32_t PriMask
|
||||
* @return none
|
||||
*
|
||||
* Set the priority mask bit in the priority mask register
|
||||
*/
|
||||
void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Fault Mask value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t FaultMask
|
||||
*
|
||||
* Return the content of the fault mask register
|
||||
*/
|
||||
uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Fault Mask value
|
||||
*
|
||||
* @param uint32_t faultMask value
|
||||
* @return none
|
||||
*
|
||||
* Set the fault mask register
|
||||
*/
|
||||
void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in integer value
|
||||
*
|
||||
* @param uint32_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse byte order in integer value
|
||||
*/
|
||||
uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in unsigned short value
|
||||
*
|
||||
* @param uint16_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse byte order in unsigned short value
|
||||
*/
|
||||
uint32_t __REV16(uint16_t value)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse byte order in signed short value with sign extension to integer
|
||||
*
|
||||
* @param int32_t value to reverse
|
||||
* @return int32_t reversed value
|
||||
*
|
||||
* Reverse byte order in signed short value with sign extension to integer
|
||||
*/
|
||||
int32_t __REVSH(int16_t value)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverse bit order of value
|
||||
*
|
||||
* @param uint32_t value to reverse
|
||||
* @return uint32_t reversed value
|
||||
*
|
||||
* Reverse bit order of value
|
||||
*/
|
||||
uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint8_t* address
|
||||
* @return uint8_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint8_t __LDREXB(uint8_t *addr)
|
||||
{
|
||||
uint8_t result=0;
|
||||
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint16_t* address
|
||||
* @return uint16_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint16_t __LDREXH(uint16_t *addr)
|
||||
{
|
||||
uint16_t result=0;
|
||||
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LDR Exclusive
|
||||
*
|
||||
* @param uint32_t* address
|
||||
* @return uint32_t value of (*address)
|
||||
*
|
||||
* Exclusive LDR command
|
||||
*/
|
||||
uint32_t __LDREXW(uint32_t *addr)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint8_t *address
|
||||
* @param uint8_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint16_t *address
|
||||
* @param uint16_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STR Exclusive
|
||||
*
|
||||
* @param uint32_t *address
|
||||
* @param uint32_t value to store
|
||||
* @return uint32_t successful / failed
|
||||
*
|
||||
* Exclusive STR command
|
||||
*/
|
||||
uint32_t __STREXW(uint32_t value, uint32_t *addr)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the Control Register value
|
||||
*
|
||||
* @param none
|
||||
* @return uint32_t Control value
|
||||
*
|
||||
* Return the content of the control register
|
||||
*/
|
||||
uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Control Register value
|
||||
*
|
||||
* @param uint32_t Control value
|
||||
* @return none
|
||||
*
|
||||
* Set the control register
|
||||
*/
|
||||
void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,88 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal FLASH on the AT91SAM3U4
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(resetHandler)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY {
|
||||
sram0 (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* Sram0, 32K */
|
||||
sram1 (W!RX) : ORIGIN = 0x20080000, LENGTH = 0x00004000 /* Sram1, 16K */
|
||||
flash0 (W!RX) : ORIGIN = 0x00080000, LENGTH = 0x00020000 /* Flash0, 128K */
|
||||
flash1 (W!RX) : ORIGIN = 0x00100000, LENGTH = 0x00020000 /* Flash1, 128K */
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
_sfixed = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
} >flash0
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
} >flash0
|
||||
|
||||
. = ALIGN(4);
|
||||
_efixed = .; /* End of text section */
|
||||
|
||||
.data : AT (_efixed) {
|
||||
. = ALIGN(4);
|
||||
_srelocate = .;
|
||||
*(.ramfunc*);
|
||||
*(.data*);
|
||||
. = ALIGN(4);
|
||||
_erelocate = .;
|
||||
} >sram0
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
_szero = .;
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram0
|
||||
|
||||
/* Stack in the end of SRAM0 */
|
||||
_estack = 0x20007FF8;
|
||||
/* DFU loader flag */
|
||||
_dfumode = 0x20007FFC;
|
||||
}
|
||||
end = .;
|
|
@ -0,0 +1,94 @@
|
|||
#ifndef INCLUDE_BOARD_H
|
||||
#define INCLUDE_BOARD_H
|
||||
|
||||
#include "at91sam3u4/AT91SAM3U4.h"
|
||||
|
||||
// frequency for the MCU crystal
|
||||
#define BOARD_CRYSTAL 12000000
|
||||
|
||||
// master clock we want to use
|
||||
//#define BOARD_MCK 48000000
|
||||
#define BOARD_MCK 96000000
|
||||
|
||||
typedef enum IRQn {
|
||||
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
|
||||
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
|
||||
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
|
||||
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
|
||||
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
|
||||
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
|
||||
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
|
||||
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
|
||||
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
|
||||
|
||||
/****** AT91SAM3U4 specific Interrupt Numbers *********************************************************/
|
||||
IROn_SUPC = AT91C_ID_SUPC, // SUPPLY CONTROLLER
|
||||
IROn_RSTC = AT91C_ID_RSTC, // RESET CONTROLLER
|
||||
IROn_RTC = AT91C_ID_RTC, // REAL TIME CLOCK
|
||||
IROn_RTT = AT91C_ID_RTT, // REAL TIME TIMER
|
||||
IROn_WDG = AT91C_ID_WDG, // WATCHDOG TIMER
|
||||
IROn_PMC = AT91C_ID_PMC, // PMC
|
||||
IROn_EFC0 = AT91C_ID_EFC0, // EFC0
|
||||
IROn_EFC1 = AT91C_ID_EFC1, // EFC1
|
||||
IROn_DBGU = AT91C_ID_DBGU, // DBGU
|
||||
IROn_HSMC4 = AT91C_ID_HSMC4, // HSMC4
|
||||
IROn_PIOA = AT91C_ID_PIOA, // Parallel IO Controller A
|
||||
IROn_PIOB = AT91C_ID_PIOB, // Parallel IO Controller B
|
||||
IROn_PIOC = AT91C_ID_PIOC, // Parallel IO Controller C
|
||||
IROn_US0 = AT91C_ID_US0, // USART 0
|
||||
IROn_US1 = AT91C_ID_US1, // USART 1
|
||||
IROn_US2 = AT91C_ID_US2, // USART 2
|
||||
IROn_US3 = AT91C_ID_US3, // USART 3
|
||||
IROn_MCI0 = AT91C_ID_MCI0, // Multimedia Card Interface
|
||||
IROn_TWI0 = AT91C_ID_TWI0, // TWI 0
|
||||
IROn_TWI1 = AT91C_ID_TWI1, // TWI 1
|
||||
IROn_SPI0 = AT91C_ID_SPI0, // Serial Peripheral Interface
|
||||
IROn_SSC0 = AT91C_ID_SSC0, // Serial Synchronous Controller 0
|
||||
IROn_TC0 = AT91C_ID_TC0, // Timer Counter 0
|
||||
IROn_TC1 = AT91C_ID_TC1, // Timer Counter 1
|
||||
IROn_TC2 = AT91C_ID_TC2, // Timer Counter 2
|
||||
IROn_PWMC = AT91C_ID_PWMC, // Pulse Width Modulation Controller
|
||||
IROn_ADCC0 = AT91C_ID_ADC12B, // ADC controller0
|
||||
IROn_ADCC1 = AT91C_ID_ADC, // ADC controller1
|
||||
IROn_HDMA = AT91C_ID_HDMA, // HDMA
|
||||
IROn_UDPHS = AT91C_ID_UDPHS // USB Device High Speed
|
||||
} IRQn_Type;
|
||||
|
||||
#define CHIP_USB_NUMENDPOINTS 7
|
||||
|
||||
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
|
||||
((i == 0) ? 64 : \
|
||||
((i == 1) ? 512 : \
|
||||
((i == 2) ? 512 : \
|
||||
((i == 3) ? 64 : \
|
||||
((i == 4) ? 64 : \
|
||||
((i == 5) ? 1024 : \
|
||||
((i == 6) ? 1024 : 0 )))))))
|
||||
|
||||
#define CHIP_USB_ENDPOINTS_BANKS(i) \
|
||||
((i == 0) ? 1 : \
|
||||
((i == 1) ? 2 : \
|
||||
((i == 2) ? 2 : \
|
||||
((i == 3) ? 3 : \
|
||||
((i == 4) ? 3 : \
|
||||
((i == 5) ? 3 : \
|
||||
((i == 6) ? 3 : 0 )))))))
|
||||
|
||||
#define CHIP_USB_ENDPOINTS_DMA(i) \
|
||||
((i == 1) ? 1 : \
|
||||
((i == 2) ? 1 : \
|
||||
((i == 3) ? 1 : \
|
||||
((i == 4) ? 1 : \
|
||||
((i == 5) ? 1 : \
|
||||
((i == 6) ? 1 : 0 ))))))
|
||||
|
||||
#define BOARD_USB_VENDOR 0x16c0
|
||||
#define BOARD_USB_PRODUCT 0x0763
|
||||
#define BOARD_USB_RELEASE 0x0100
|
||||
|
||||
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
|
||||
#define BOARD_DFU_PAGE_SIZE 512
|
||||
|
||||
#define BOARD_USB_NUMINTERFACES 1
|
||||
|
||||
#endif // INCLUDE_BOARD_H
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "types.h"
|
||||
|
||||
void printf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
uint i;
|
||||
char printbuffer[PRINTF_BUFSIZE];
|
||||
|
||||
//format the string
|
||||
va_start (args, fmt);
|
||||
i = vsprintf(printbuffer, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
//print the string
|
||||
puts(printbuffer);
|
||||
}
|
||||
|
||||
void dprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
uint i;
|
||||
char printbuffer[PRINTF_BUFSIZE];
|
||||
|
||||
//format the string
|
||||
va_start (args, fmt);
|
||||
i = vsprintf(printbuffer, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
//print the string
|
||||
dputs(printbuffer);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
int sprintf(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "../driver/dbgio.h"
|
||||
|
||||
void puts(const char* str)
|
||||
{
|
||||
while(*str != '\0') {
|
||||
if(*str == '\n')
|
||||
dbgio_putChar('\r');
|
||||
dbgio_putChar(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
void dputs(const char* str)
|
||||
{
|
||||
while(*str != '\0') {
|
||||
if(*str == '\n')
|
||||
dbgio_putCharDirect('\r');
|
||||
dbgio_putCharDirect(*str++);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef INCLUDE_STDIO_H
|
||||
#define INCLUDE_STDIO_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define PRINTF_BUFSIZE 96
|
||||
|
||||
void printf(const char *fmt, ...);
|
||||
void dprintf(const char *fmt, ...);
|
||||
void vprintf(const char *fmt, va_list args);
|
||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
void puts(const char* str);
|
||||
void dputs(const char* str);
|
||||
|
||||
#endif // INCLUDE_STDIO_H
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef INCLUDE_TYPES_H
|
||||
#define INCLUDE_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef int64_t s64;
|
||||
typedef uint32_t u32;
|
||||
typedef int32_t s32;
|
||||
typedef uint16_t u16;
|
||||
typedef int16_t s16;
|
||||
typedef uint8_t u8;
|
||||
typedef int8_t s8;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
typedef enum Bool_ {
|
||||
False = 0,
|
||||
True = 1
|
||||
} Bool;
|
||||
|
||||
#endif // INCLUDE_TYPES_H
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "types.h"
|
||||
|
||||
void vprintf (const char *fmt, va_list args)
|
||||
{
|
||||
uint i;
|
||||
char printbuffer[PRINTF_BUFSIZE];
|
||||
|
||||
//format the string
|
||||
i = vsprintf (printbuffer, fmt, args);
|
||||
|
||||
//print the string
|
||||
puts(printbuffer);
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
static int strnlen(const char * s, int count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for(sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
/* we use this so that we can do without the ctype library */
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while(is_digit(**s))
|
||||
i = i * 10 + *((*s)++) - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
#define do_div(n,base) ({ \
|
||||
int __res; \
|
||||
__res = ((unsigned long) n) % (unsigned) base; \
|
||||
n = ((unsigned long) n) / (unsigned) base; \
|
||||
__res; \
|
||||
})
|
||||
|
||||
static char * number(char * str, long num, int base, int size, int precision, int type)
|
||||
{
|
||||
char c, sign, tmp[66];
|
||||
const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
int i;
|
||||
|
||||
if(type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
if(base < 2 || base > 36)
|
||||
return 0;
|
||||
c = (type & ZEROPAD) ? '0' : ' ';
|
||||
sign = 0;
|
||||
if(type & SIGN) {
|
||||
if(num < 0) {
|
||||
sign = '-';
|
||||
num = -num;
|
||||
size--;
|
||||
} else if(type & PLUS) {
|
||||
sign = '+';
|
||||
size--;
|
||||
} else if(type & SPACE) {
|
||||
sign = ' ';
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if(type & SPECIAL) {
|
||||
if(base == 16)
|
||||
size -= 2;
|
||||
else if(base == 8)
|
||||
size--;
|
||||
}
|
||||
i = 0;
|
||||
if(num == 0)
|
||||
tmp[i++] = '0';
|
||||
else while(num != 0)
|
||||
tmp[i++] = digits[do_div(num,base)];
|
||||
if(i > precision)
|
||||
precision = i;
|
||||
size -= precision;
|
||||
if(!(type & (ZEROPAD + LEFT)))
|
||||
while(size-- > 0)
|
||||
*str++ = ' ';
|
||||
if(sign)
|
||||
*str++ = sign;
|
||||
if(type & SPECIAL) {
|
||||
if(base == 8)
|
||||
*str++ = '0';
|
||||
else if(base == 16) {
|
||||
*str++ = '0';
|
||||
*str++ = digits[33];
|
||||
}
|
||||
}
|
||||
if(!(type & LEFT))
|
||||
while(size-- > 0)
|
||||
*str++ = c;
|
||||
while(i < precision--)
|
||||
*str++ = '0';
|
||||
while(i-- > 0)
|
||||
*str++ = tmp[i];
|
||||
while(size-- > 0)
|
||||
*str++ = ' ';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Forward decl. needed for IP address printing stuff... */
|
||||
int sprintf(char * buf, const char *fmt, ...);
|
||||
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long num;
|
||||
int i, base;
|
||||
char * str;
|
||||
const char *s;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
int field_width; /* width of output field */
|
||||
int precision; /* min. # of digits for integers; max
|
||||
number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'q' for integer fields */
|
||||
|
||||
for(str = buf; *fmt; ++fmt) {
|
||||
if(*fmt != '%') {
|
||||
*str++ = *fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
repeat: ++fmt; /* this also skips first '%' */
|
||||
switch(*fmt) {
|
||||
case '-':
|
||||
flags |= LEFT;
|
||||
goto repeat;
|
||||
case '+':
|
||||
flags |= PLUS;
|
||||
goto repeat;
|
||||
case ' ':
|
||||
flags |= SPACE;
|
||||
goto repeat;
|
||||
case '#':
|
||||
flags |= SPECIAL;
|
||||
goto repeat;
|
||||
case '0':
|
||||
flags |= ZEROPAD;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if(is_digit(*fmt))
|
||||
field_width = skip_atoi(&fmt);
|
||||
else if(*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
field_width = va_arg(args, int);
|
||||
if(field_width < 0) {
|
||||
field_width = -field_width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
if(*fmt == '.') {
|
||||
++fmt;
|
||||
if(is_digit(*fmt))
|
||||
precision = skip_atoi(&fmt);
|
||||
else if(*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
precision = va_arg(args, int);
|
||||
}
|
||||
if(precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
/* get the conversion qualifier */
|
||||
qualifier = -1;
|
||||
if(*fmt == 'h' || *fmt == 'l' || *fmt == 'q') {
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
/* default base */
|
||||
base = 10;
|
||||
|
||||
switch(*fmt) {
|
||||
case 'c':
|
||||
if(!(flags & LEFT))
|
||||
while(--field_width > 0)
|
||||
*str++ = ' ';
|
||||
*str++ = (unsigned char)va_arg(args, int);
|
||||
while(--field_width > 0)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if(!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = strnlen(s, precision);
|
||||
|
||||
if(!(flags & LEFT))
|
||||
while(len < field_width--)
|
||||
*str++ = ' ';
|
||||
for(i = 0; i < len; ++i)
|
||||
*str++ = *s++;
|
||||
while(len < field_width--)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
if(field_width == -1) {
|
||||
field_width = 2 * sizeof(void *);
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
str = number(str, (unsigned long)va_arg(args, void *), 16, field_width, precision, flags);
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
if(qualifier == 'l') {
|
||||
long * ip = va_arg(args, long *);
|
||||
*ip = (str - buf);
|
||||
} else {
|
||||
int * ip = va_arg(args, int *);
|
||||
*ip = (str - buf);
|
||||
}
|
||||
continue;
|
||||
|
||||
case '%':
|
||||
*str++ = '%';
|
||||
continue;
|
||||
|
||||
/* integer number formats - set up the flags and "break" */
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= LARGE;
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
base = 2;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= SIGN;
|
||||
case 'u':
|
||||
break;
|
||||
|
||||
default:
|
||||
*str++ = '%';
|
||||
if(*fmt)
|
||||
*str++ = *fmt;
|
||||
else --fmt;
|
||||
continue;
|
||||
}
|
||||
if(qualifier == 'l')
|
||||
num = va_arg(args, unsigned long);
|
||||
else if(qualifier == 'h') {
|
||||
num = (unsigned short)va_arg(args, int);
|
||||
if(flags & SIGN)
|
||||
num = (short)num;
|
||||
} else if(flags & SIGN)
|
||||
num = va_arg(args, int);
|
||||
else num = va_arg(args, unsigned int);
|
||||
str = number(str, num, base, field_width, precision, flags);
|
||||
}
|
||||
*str = '\0';
|
||||
return str - buf;
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dbgio.h"
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
#include "../board.h"
|
||||
#include "../at91sam3u4/core_cm3.h"
|
||||
#include "irq.h"
|
||||
|
||||
#define FIFO_SIZE_BITS 7
|
||||
|
||||
typedef struct DebugUart_ {
|
||||
u8 rxFifo[1 << FIFO_SIZE_BITS];
|
||||
u8 txFifo[1 << FIFO_SIZE_BITS];
|
||||
uint rxWPos;
|
||||
uint rxRPos;
|
||||
uint txWPos;
|
||||
volatile uint txRPos;
|
||||
} DebugUart;
|
||||
|
||||
static DebugUart g_debugUart;
|
||||
|
||||
void dbgio_irqHandler(void)
|
||||
{
|
||||
u8 c;
|
||||
uint wPos;
|
||||
uint csr = AT91C_BASE_DBGU->DBGU_CSR & AT91C_BASE_DBGU->DBGU_IMR;
|
||||
|
||||
// receive data register full
|
||||
if(csr & AT91C_US_RXRDY) {
|
||||
// read character
|
||||
c = AT91C_BASE_DBGU->DBGU_RHR;
|
||||
|
||||
// put character into FIFO
|
||||
wPos = (g_debugUart.rxWPos + 1) % (1 << FIFO_SIZE_BITS);
|
||||
if(wPos != g_debugUart.rxRPos) {
|
||||
g_debugUart.rxFifo[g_debugUart.rxWPos] = c;
|
||||
g_debugUart.rxWPos = wPos;
|
||||
}
|
||||
}
|
||||
|
||||
// transmit data register empty
|
||||
if(csr & AT91C_US_TXEMPTY) {
|
||||
// check if we have more to send
|
||||
if(g_debugUart.txWPos != g_debugUart.txRPos) {
|
||||
c = g_debugUart.txFifo[g_debugUart.txRPos];
|
||||
g_debugUart.txRPos = (g_debugUart.txRPos + 1) % (1 << FIFO_SIZE_BITS);
|
||||
|
||||
// write character
|
||||
AT91C_BASE_DBGU->DBGU_THR = c;
|
||||
} else {
|
||||
// no more bytes to send -> switch off interrupt
|
||||
AT91C_BASE_DBGU->DBGU_IDR = AT91C_US_TXEMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbgio_configure(uint baudrate)
|
||||
{
|
||||
// enable clock for UART
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_DBGU);
|
||||
|
||||
// configure PINs for DBGU
|
||||
// RXD
|
||||
AT91C_BASE_PIOA->PIO_IDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_MDDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_ABSR &= ~AT91C_PIO_PA11;
|
||||
// TXD
|
||||
AT91C_BASE_PIOA->PIO_IDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_MDDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_ABSR &= ~AT91C_PIO_PA12;
|
||||
|
||||
// reset & disable receiver and transmitter, disable interrupts
|
||||
AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
|
||||
AT91C_BASE_DBGU->DBGU_IDR = 0xffffffff;
|
||||
|
||||
// Configure baud rate
|
||||
AT91C_BASE_DBGU->DBGU_BRGR = BOARD_MCK / (baudrate * 16);
|
||||
|
||||
// Configure mode register
|
||||
AT91C_BASE_DBGU->DBGU_MR = AT91C_US_PAR_NONE;
|
||||
|
||||
// Disable DMA channel
|
||||
AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||
|
||||
// setup FIFO
|
||||
g_debugUart.rxWPos = 0;
|
||||
g_debugUart.rxRPos = 0;
|
||||
g_debugUart.txWPos = 0;
|
||||
g_debugUart.txRPos = 0;
|
||||
|
||||
// configure IRQ
|
||||
irq_configure(AT91C_ID_DBGU, 0);
|
||||
irq_enable(AT91C_ID_DBGU);
|
||||
AT91C_BASE_DBGU->DBGU_IER = AT91C_DBGU_RXRDY;
|
||||
|
||||
// Enable receiver and transmitter
|
||||
AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;
|
||||
}
|
||||
|
||||
int dbgio_getChar(void)
|
||||
{
|
||||
u32 faultmask = __get_FAULTMASK();
|
||||
int res;
|
||||
|
||||
__disable_fault_irq();
|
||||
|
||||
// if we have a character, get it and advance FIFO
|
||||
if(g_debugUart.rxWPos != g_debugUart.rxRPos) {
|
||||
res = g_debugUart.rxFifo[g_debugUart.rxRPos];
|
||||
g_debugUart.rxRPos = (g_debugUart.rxRPos + 1) % (1 << FIFO_SIZE_BITS);
|
||||
} else {
|
||||
// otherwise, return -1
|
||||
res = -1;
|
||||
}
|
||||
|
||||
__set_FAULTMASK(faultmask);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void dbgio_putChar(u8 c)
|
||||
{
|
||||
u32 faultmask = __get_FAULTMASK();
|
||||
uint wPos;
|
||||
|
||||
__disable_fault_irq();
|
||||
|
||||
// if uart is running, feed the character to the FIFO
|
||||
if(AT91C_BASE_DBGU->DBGU_IMR & AT91C_DBGU_TXEMPTY) {
|
||||
// check if there is space in the FIFO
|
||||
wPos = (g_debugUart.txWPos + 1) % (1 << FIFO_SIZE_BITS);
|
||||
if(wPos == g_debugUart.txRPos) {
|
||||
// FIFO full - wait for a free space
|
||||
if(!faultmask) {
|
||||
// ...but only if we're not in an IRQ
|
||||
__set_FAULTMASK(faultmask);
|
||||
while(wPos == g_debugUart.txRPos) ;
|
||||
__disable_fault_irq();
|
||||
} else {
|
||||
// sorry, can't help here
|
||||
return;
|
||||
}
|
||||
}
|
||||
// check if it is still running - otherwise fall through and restart UART
|
||||
if(AT91C_BASE_DBGU->DBGU_IMR & AT91C_DBGU_TXEMPTY) {
|
||||
// feed characater into FIFO
|
||||
g_debugUart.txFifo[g_debugUart.txWPos] = c;
|
||||
g_debugUart.txWPos = wPos;
|
||||
__set_FAULTMASK(faultmask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// send directly and start FIFO
|
||||
AT91C_BASE_DBGU->DBGU_IER = AT91C_US_TXEMPTY;
|
||||
AT91C_BASE_DBGU->DBGU_THR = c;
|
||||
|
||||
__set_FAULTMASK(faultmask);
|
||||
}
|
||||
|
||||
void dbgio_putCharDirect(u8 c)
|
||||
{
|
||||
while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);
|
||||
AT91C_BASE_DBGU->DBGU_THR = c;
|
||||
}
|
||||
|
||||
Bool dbgio_isRxReady(void)
|
||||
{
|
||||
u32 faultmask = __get_FAULTMASK();
|
||||
Bool res;
|
||||
|
||||
__disable_fault_irq();
|
||||
|
||||
res = (g_debugUart.rxWPos != g_debugUart.rxRPos) ? True : False;
|
||||
|
||||
__set_FAULTMASK(faultmask);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void dbgio_flushOutput(void)
|
||||
{
|
||||
while(g_debugUart.txWPos != g_debugUart.txRPos) __NOP();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef INCLUDE_DBGIO_H
|
||||
#define INCLUDE_DBGIO_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
|
||||
void dbgio_configure(uint baudrate);
|
||||
int dbgio_getChar(void);
|
||||
void dbgio_putChar(u8 c);
|
||||
void dbgio_putCharDirect(u8 c);
|
||||
Bool dbgio_isRxReady(void);
|
||||
void dbgio_flushOutput(void);
|
||||
|
||||
#endif // INCLUDE_DBGIO_H
|
|
@ -0,0 +1,153 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "flash.h"
|
||||
#include "../crt/stdio.h"
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
#include "../board.h"
|
||||
#include "../at91sam3u4/core_cm3.h"
|
||||
#include "sys.h"
|
||||
|
||||
static __attribute__((section(".ramfunc"))) uint32_t _flash_get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
static __attribute__((section(".ramfunc"))) void _flash_set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
|
||||
}
|
||||
|
||||
extern u32 _dfumode;
|
||||
#define DFU_MAGIC 0xcd220778
|
||||
|
||||
__attribute__((section(".ramfunc"))) void flash_readUID(char* uid)
|
||||
{
|
||||
u32 faultmask = _flash_get_FAULTMASK() ;
|
||||
__disable_fault_irq();
|
||||
|
||||
// reset pipeline
|
||||
__ISB(0);
|
||||
__DSB(0);
|
||||
|
||||
while((AT91C_BASE_EFC0->EFC_FSR & AT91C_EFC_FRDY_S) != AT91C_EFC_FRDY_S) __NOP();
|
||||
|
||||
AT91C_BASE_EFC0->EFC_FCR = 0x5a00000e;
|
||||
while((AT91C_BASE_EFC0->EFC_FSR & AT91C_EFC_FRDY_S) == AT91C_EFC_FRDY_S) __NOP();
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
uid[i] = ((volatile u8*)AT91C_IFLASH0)[i];
|
||||
uid[16] = '\0';
|
||||
|
||||
AT91C_BASE_EFC0->EFC_FCR = 0x5a00000f;
|
||||
while((AT91C_BASE_EFC0->EFC_FSR & AT91C_EFC_FRDY_S) != AT91C_EFC_FRDY_S) __NOP();
|
||||
|
||||
// reset pipeline
|
||||
((volatile u32*)AT91C_IFLASH0)[0];
|
||||
__ISB(0);
|
||||
__DSB(0);
|
||||
|
||||
_flash_set_FAULTMASK(faultmask);
|
||||
}
|
||||
|
||||
__attribute__((section(".ramfunc"))) int flash_write_bank0(u32 addr, const u8* data, uint len)
|
||||
{
|
||||
u32 faultmask = _flash_get_FAULTMASK();
|
||||
AT91PS_EFC efc = AT91C_BASE_EFC0;
|
||||
u32* flashBase = (u32*)AT91C_IFLASH0;
|
||||
u32 blockLen;
|
||||
int res = 0;
|
||||
|
||||
// make sure we're starting on a new page
|
||||
if((addr & (AT91C_IFLASH0_PAGE_SIZE - 1)) != 0)
|
||||
return -1;
|
||||
|
||||
__disable_fault_irq();
|
||||
|
||||
__ISB(0);
|
||||
__DSB(0);
|
||||
|
||||
AT91C_BASE_EFC0->EFC_FMR = ((6 << 8) & AT91C_EFC_FWS);
|
||||
AT91C_BASE_EFC1->EFC_FMR = ((6 << 8) & AT91C_EFC_FWS);
|
||||
|
||||
while((efc->EFC_FSR & AT91C_EFC_FRDY_S) != AT91C_EFC_FRDY_S) __NOP();
|
||||
|
||||
while(len > 0) {
|
||||
blockLen = len;
|
||||
if(blockLen > AT91C_IFLASH0_PAGE_SIZE)
|
||||
blockLen = AT91C_IFLASH0_PAGE_SIZE;
|
||||
|
||||
// send data to flash
|
||||
for(int i = 0; i < blockLen / 4; i++)
|
||||
flashBase[i] = *(const u32*)&data[i * 4];
|
||||
|
||||
// erase + program
|
||||
efc->EFC_FCR = 0x5a000000 | (((addr - AT91C_IFLASH0) / AT91C_IFLASH0_PAGE_SIZE) << 8) | 0x03;
|
||||
|
||||
// wait until finished
|
||||
while((efc->EFC_FSR & AT91C_EFC_FRDY_S) == AT91C_EFC_FRDY_S) __NOP();
|
||||
while((efc->EFC_FSR & AT91C_EFC_FRDY_S) != AT91C_EFC_FRDY_S) __NOP();
|
||||
|
||||
// verify
|
||||
for(int i = 0; i < blockLen; i++) {
|
||||
if((*(const u8*)(addr + i)) != data[i]) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addr += blockLen;
|
||||
data += blockLen;
|
||||
len -= blockLen;
|
||||
}
|
||||
|
||||
AT91C_BASE_EFC0->EFC_FMR = AT91C_EFC_FWS_2WS;
|
||||
AT91C_BASE_EFC1->EFC_FMR = AT91C_EFC_FWS_2WS;
|
||||
|
||||
// reset cacheline
|
||||
((volatile u32*)AT91C_IFLASH0)[0];
|
||||
__ISB(0);
|
||||
__DSB(0);
|
||||
|
||||
_flash_set_FAULTMASK(faultmask);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__attribute__((section(".ramfunc"))) void flash_write_loader(const u8* data)
|
||||
{
|
||||
__disable_irq();
|
||||
__disable_fault_irq();
|
||||
|
||||
for(int i = 0; i < 16384; i += AT91C_IFLASH0_PAGE_SIZE)
|
||||
flash_write_bank0(AT91C_IFLASH0 + i, data + i, AT91C_IFLASH0_PAGE_SIZE);
|
||||
|
||||
// here is no way back - but go to DFU again
|
||||
_dfumode = DFU_MAGIC;
|
||||
|
||||
AT91C_BASE_UDPHS->UDPHS_CTRL |= AT91C_UDPHS_DETACH; // detach
|
||||
AT91C_BASE_UDPHS->UDPHS_CTRL |= AT91C_UDPHS_PULLD_DIS; // Disable Pull Down
|
||||
|
||||
for(volatile int i = 0; i < 2500000; i++) __NOP();
|
||||
|
||||
AT91C_BASE_RSTC->RSTC_RCR = 0xa5000000 | AT91C_RSTC_PROCRST | AT91C_RSTC_ICERST | AT91C_RSTC_PERRST | AT91C_RSTC_EXTRST;
|
||||
while(1) ;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef INCLUDE_FLASH_H
|
||||
#define INCLUDE_FLASH_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
|
||||
void flash_readUID(char* uid);
|
||||
int flash_write_bank0(u32 addr, const u8* data, uint len);
|
||||
void flash_write_loader(const u8* data);
|
||||
|
||||
#endif // INCLUDE_FLASH_H
|
|
@ -0,0 +1,71 @@
|
|||
/* This file uses lots of code from the Atmel reference library:
|
||||
* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 "irq.h"
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
#include "../board.h"
|
||||
#include "../at91sam3u4/core_cm3.h"
|
||||
|
||||
void irq_configure(uint source, uint priority)
|
||||
{
|
||||
uint priGroup = __NVIC_PRIO_BITS;
|
||||
uint nPre = 8 - priGroup;
|
||||
uint nSub = priGroup;
|
||||
uint preemptionPriority;
|
||||
uint subPriority;
|
||||
uint irqPriority;
|
||||
|
||||
preemptionPriority = (priority & 0xff00) >> 8;
|
||||
subPriority = (priority & 0xff);
|
||||
|
||||
// Disable the interrupt first
|
||||
NVIC_DisableIRQ((IRQn_Type)source);
|
||||
|
||||
// Clear any pending status
|
||||
NVIC_ClearPendingIRQ((IRQn_Type)source);
|
||||
|
||||
if(subPriority >= (0x01 << nSub))
|
||||
subPriority = (0x01 << nSub) - 1;
|
||||
if(preemptionPriority >= (0x01 << nPre))
|
||||
preemptionPriority = (0x01 << nPre) - 1;
|
||||
|
||||
irqPriority = (subPriority | (preemptionPriority << nSub));
|
||||
NVIC_SetPriority((IRQn_Type)source, irqPriority);
|
||||
}
|
||||
|
||||
void irq_enable(uint source)
|
||||
{
|
||||
NVIC_EnableIRQ((IRQn_Type)source);
|
||||
}
|
||||
|
||||
void irq_disable(uint source)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)source);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef INCLUDE_IRQ_H
|
||||
#define INCLUDE_IRQ_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
|
||||
void irq_configure(uint source, uint priority);
|
||||
void irq_enable(uint source);
|
||||
void irq_disable(uint source);
|
||||
|
||||
#endif // INCLUDE_IRQ_H
|
|
@ -0,0 +1,38 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "led.h"
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
|
||||
void led_configure()
|
||||
{
|
||||
AT91C_BASE_PIOB->PIO_IDR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_MDDR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB18;
|
||||
|
||||
AT91C_BASE_PIOB->PIO_IDR = AT91C_PIO_PB19;
|
||||
AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PIO_PB19;
|
||||
AT91C_BASE_PIOB->PIO_MDDR = AT91C_PIO_PB19;
|
||||
AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB19;
|
||||
AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB19;
|
||||
|
||||
AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB19;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef INCLUDE_LED_H
|
||||
#define INCLUDE_LED_H
|
||||
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
#include "../crt/types.h"
|
||||
|
||||
void led_configure();
|
||||
|
||||
static inline void led_externalSet(Bool on)
|
||||
{
|
||||
if(on)
|
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB18;
|
||||
else AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB18;
|
||||
}
|
||||
|
||||
static inline void led_internalSet(Bool on)
|
||||
{
|
||||
if(on)
|
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB19;
|
||||
else AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB19;
|
||||
}
|
||||
|
||||
#endif // INCLUDE_LED_H
|
|
@ -0,0 +1,30 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sys.h"
|
||||
#include "../at91sam3u4/AT91SAM3U4.h"
|
||||
#include "../board.h"
|
||||
#include "../at91sam3u4/core_cm3.h"
|
||||
|
||||
void sys_reset(void)
|
||||
{
|
||||
__disable_fault_irq();
|
||||
__disable_irq();
|
||||
AT91C_BASE_RSTC->RSTC_RCR = 0xa5000000 | AT91C_RSTC_PROCRST | AT91C_RSTC_ICERST | AT91C_RSTC_PERRST | AT91C_RSTC_EXTRST;
|
||||
while(1) ;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef INCLUDE_SYS_H
|
||||
#define INCLUDE_SYS_H
|
||||
|
||||
void sys_reset(void);
|
||||
|
||||
#endif // INCLUDE_SYS_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
#ifndef INCLUDE_USBD_H
|
||||
#define INCLUDE_USBD_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
#include "../usb/descriptors.h"
|
||||
|
||||
/// The device is currently suspended.
|
||||
#define USBD_STATE_SUSPENDED 0
|
||||
/// USB cable is plugged into the device.
|
||||
#define USBD_STATE_ATTACHED 1
|
||||
/// Host is providing +5V through the USB cable.
|
||||
#define USBD_STATE_POWERED 2
|
||||
/// Device has been reset.
|
||||
#define USBD_STATE_DEFAULT 3
|
||||
/// The device has been given an address on the bus.
|
||||
#define USBD_STATE_ADDRESS 4
|
||||
/// A valid configuration has been selected.
|
||||
#define USBD_STATE_CONFIGURED 5
|
||||
|
||||
/// Indicates the operation was successful.
|
||||
#define USBD_STATUS_SUCCESS 0
|
||||
/// Endpoint/device is already busy.
|
||||
#define USBD_STATUS_LOCKED 1
|
||||
/// Operation has been aborted.
|
||||
#define USBD_STATUS_ABORTED 2
|
||||
/// Operation has been aborted because the device has been reset.
|
||||
#define USBD_STATUS_RESET 3
|
||||
/// Part ot operation successfully done.
|
||||
#define USBD_STATUS_PARTIAL_DONE 4
|
||||
/// Operation failed because parameter error
|
||||
#define USBD_STATUS_INVALID_PARAMETER 5
|
||||
/// Operation failed because in unexpected state
|
||||
#define USBD_STATUS_WRONG_STATE 6
|
||||
/// Operation failed because HW not supported
|
||||
#define USBD_STATUS_HW_NOT_SUPPORTED 0xFE
|
||||
|
||||
typedef void (*TransferCallback)(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining);
|
||||
|
||||
void usbdhs_configure(void);
|
||||
void usbdhs_connect(void);
|
||||
void usbdhs_setConfiguration(uint cfgnum);
|
||||
void usbdhs_configureEndpoint(const USBEndpointDescriptor* pDescriptor);
|
||||
char usbdhs_write(unsigned char bEndpoint, const void *pData, unsigned int dLength, TransferCallback fCallback, void *pArgument);
|
||||
char usbdhs_read(unsigned char bEndpoint, void *pData, unsigned int dLength, TransferCallback fCallback, void *pArgument);
|
||||
unsigned char usbdhs_stall(uint endpoint);
|
||||
Bool usbdhs_isHighSpeed(void);
|
||||
Bool usbdhs_isHalted(uint endpoint);
|
||||
void usbdhs_setAddress(uint address);
|
||||
|
||||
#endif // INCLUDE_USBD_H
|
|
@ -0,0 +1,76 @@
|
|||
/* (C) 2011-2012 by Christian Daniel <cd@maintech.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "crt/stdio.h"
|
||||
#include "driver/dbgio.h"
|
||||
#include "driver/led.h"
|
||||
#include "driver/flash.h"
|
||||
#include "driver/sys.h"
|
||||
#include "driver/usbdhs.h"
|
||||
#include "usb/usbdevice.h"
|
||||
#include "../build/buildid.h"
|
||||
|
||||
// USB VDD monitoring pin: PB10
|
||||
|
||||
static void displaySN()
|
||||
{
|
||||
char sn[17];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
sn[i] = '0';
|
||||
sn[sizeof(sn) - 1] = '\0';
|
||||
flash_readUID(sn);
|
||||
usbDevice_setSerial(sn);
|
||||
printf("-- s/n %s --\n\n", sn);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
dbgio_configure(115200);
|
||||
|
||||
printf("\n\n** OsmoSDR ** running in DFU mode **\n");
|
||||
printf("-- %s %s %s @%s -- %s --\n", BUILDID_DATE, BUILDID_TIME, BUILDID_ZONE, BUILDID_HOST, BUILDID_VCSID);
|
||||
printf("-- %s --\n", BUILDID_GCC);
|
||||
displaySN();
|
||||
printf("Press 'r' for reboot.\n");
|
||||
dbgio_flushOutput();
|
||||
|
||||
usbDevice_configure();
|
||||
usbdhs_configure();
|
||||
usbdhs_connect();
|
||||
|
||||
while(1) {
|
||||
for(volatile uint i = 0; i < 1000000; i++) ;
|
||||
led_internalSet(1);
|
||||
for(volatile uint i = 0; i < 1000000; i++) ;
|
||||
led_internalSet(0);
|
||||
|
||||
if(dbgio_isRxReady()) {
|
||||
int c;
|
||||
while((c = dbgio_getChar()) >= 0) {
|
||||
if(c == 'r')
|
||||
sys_reset();
|
||||
}
|
||||
printf("Press 'r' for reboot.\n");
|
||||
}
|
||||
|
||||
usbDevice_tick();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
/* This file uses lots of code from the Atmel reference library:
|
||||
* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 "crt/types.h"
|
||||
#include "at91sam3u4/AT91SAM3U4.h"
|
||||
#include "board.h"
|
||||
#include "at91sam3u4/core_cm3.h"
|
||||
#include "vectors.h"
|
||||
#include "driver/led.h"
|
||||
|
||||
int main(void);
|
||||
|
||||
// initialize segments
|
||||
extern const u32 _sfixed;
|
||||
extern const u32 _efixed;
|
||||
extern u32 _srelocate;
|
||||
extern u32 _erelocate;
|
||||
extern u32 _szero;
|
||||
extern u32 _ezero;
|
||||
|
||||
extern volatile u32 _dfumode;
|
||||
#define DFU_MAGIC 0xcd220778
|
||||
|
||||
#define AT91C_CKGR_MUL_SHIFT 16
|
||||
#define AT91C_CKGR_OUT_SHIFT 14
|
||||
#define AT91C_CKGR_PLLCOUNT_SHIFT 8
|
||||
#define AT91C_CKGR_DIV_SHIFT 0
|
||||
|
||||
#if (BOARD_MCK == 48000000)
|
||||
// settings at 48/48MHz
|
||||
#define BOARD_OSCOUNT (AT91C_CKGR_MOSCXTST & (0x8 << 8))
|
||||
#define BOARD_PLLR ((1 << 29) | (0x7 << AT91C_CKGR_MUL_SHIFT) \
|
||||
| (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x1 << AT91C_CKGR_PLLCOUNT_SHIFT) \
|
||||
| (0x1 << AT91C_CKGR_DIV_SHIFT))
|
||||
#define BOARD_MCKR ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK)
|
||||
#elif (BOARD_MCK == 96000000)
|
||||
// settings at 96/96MHz
|
||||
#define BOARD_OSCOUNT (AT91C_CKGR_MOSCXTST & (0x8 << 8))
|
||||
#define BOARD_PLLR ((1 << 29) | (0x7 << AT91C_CKGR_MUL_SHIFT) \
|
||||
| (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x1 << AT91C_CKGR_PLLCOUNT_SHIFT) \
|
||||
| (0x1 << AT91C_CKGR_DIV_SHIFT))
|
||||
#define BOARD_MCKR ( AT91C_PMC_PRES_CLK | AT91C_PMC_CSS_PLLA_CLK)
|
||||
#else
|
||||
#error "no matched BOARD_MCK"
|
||||
#endif
|
||||
|
||||
// define clock timeout
|
||||
#define CLOCK_TIMEOUT 0xFFFFFFFF
|
||||
|
||||
static void startApplication(void)
|
||||
{
|
||||
u32 mode = _dfumode;
|
||||
|
||||
if(mode == DFU_MAGIC) {
|
||||
_dfumode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const u32* app = (u32*)(AT91C_IFLASH0 + 16384);
|
||||
void (*appReset)(void) = (void(*)(void))app[1];
|
||||
|
||||
if((u32)appReset == 0xffffffff)
|
||||
return;
|
||||
AT91C_BASE_NVIC->NVIC_VTOFFR = ((u32)(app)) | (0x0 << 7);
|
||||
appReset();
|
||||
}
|
||||
|
||||
static void setDefaultMaster(uint enable)
|
||||
{
|
||||
// Set default master
|
||||
if(enable == 1) {
|
||||
// set default master: SRAM0 -> Cortex-M3 System
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG0 |= AT91C_MATRIX_FIXED_DEFMSTR_SCFG0_ARMS | AT91C_MATRIX_DEFMSTR_TYPE_FIXED_DEFMSTR;
|
||||
// set default master: SRAM1 -> Cortex-M3 System
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG1 |= AT91C_MATRIX_FIXED_DEFMSTR_SCFG1_ARMS | AT91C_MATRIX_DEFMSTR_TYPE_FIXED_DEFMSTR;
|
||||
// set default master: internal flash0 -> Cortex-M3 Instruction/Data
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG3 |= AT91C_MATRIX_FIXED_DEFMSTR_SCFG3_ARMC | AT91C_MATRIX_DEFMSTR_TYPE_FIXED_DEFMSTR;
|
||||
} else {
|
||||
// Clear default master: SRAM0 -> Cortex-M3 System
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG0 &= (~AT91C_MATRIX_DEFMSTR_TYPE);
|
||||
// Clear default master: SRAM1 -> Cortex-M3 System
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG1 &= (~AT91C_MATRIX_DEFMSTR_TYPE);
|
||||
// Clear default master: Internal flash0 -> Cortex-M3 Instruction/Data
|
||||
AT91C_BASE_MATRIX->HMATRIX2_SCFG3 &= (~AT91C_MATRIX_DEFMSTR_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
static void preInit(void)
|
||||
{
|
||||
// switch to 8MHz RC oscillator
|
||||
//AT91C_BASE_PMC->PMC_MOR = (0x37 << 16) | AT91C_CKGR_MOSCRCEN | (1 << 4);
|
||||
// enable clock for UART
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_DBGU);
|
||||
|
||||
// configure PINs for DBGU
|
||||
// RXD
|
||||
AT91C_BASE_PIOA->PIO_IDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_MDDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA11;
|
||||
AT91C_BASE_PIOA->PIO_ABSR &= ~AT91C_PIO_PA11;
|
||||
// TXD
|
||||
AT91C_BASE_PIOA->PIO_IDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_MDDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA12;
|
||||
AT91C_BASE_PIOA->PIO_ABSR &= ~AT91C_PIO_PA12;
|
||||
|
||||
// reset & disable receiver and transmitter, disable interrupts
|
||||
AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
|
||||
AT91C_BASE_DBGU->DBGU_IDR = 0xffffffff;
|
||||
|
||||
// Configure baud rate
|
||||
AT91C_BASE_DBGU->DBGU_BRGR = 4000000 / (115200 * 16);
|
||||
|
||||
// Configure mode register
|
||||
AT91C_BASE_DBGU->DBGU_MR = AT91C_US_PAR_NONE;
|
||||
|
||||
// Disable DMA channel
|
||||
AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||
|
||||
// Enable transmitter
|
||||
AT91C_BASE_DBGU->DBGU_CR = AT91C_US_TXEN;
|
||||
}
|
||||
|
||||
static void putCharDirect(u8 c)
|
||||
{
|
||||
while((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);
|
||||
AT91C_BASE_DBGU->DBGU_THR = c;
|
||||
}
|
||||
|
||||
static void putStrDirect(const char* str)
|
||||
{
|
||||
while(*str != '\0')
|
||||
putCharDirect(*str++);
|
||||
}
|
||||
|
||||
static void lowLevelInit(void)
|
||||
{
|
||||
uint timeout;
|
||||
|
||||
// set 2 WS for Embedded Flash Access
|
||||
AT91C_BASE_EFC0->EFC_FMR = AT91C_EFC_FWS_2WS;
|
||||
AT91C_BASE_EFC1->EFC_FMR = AT91C_EFC_FWS_2WS;
|
||||
|
||||
// disable watchdog
|
||||
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||
|
||||
// initialize main oscillator (if not yet active)
|
||||
if(!(AT91C_BASE_PMC->PMC_MOR & AT91C_CKGR_MOSCSEL)) {
|
||||
AT91C_BASE_PMC->PMC_MOR = (0x37 << 16) | BOARD_OSCOUNT | AT91C_CKGR_MOSCRCEN | AT91C_CKGR_MOSCXTEN;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
}
|
||||
|
||||
// switch to 3-20MHz Xtal oscillator
|
||||
AT91C_BASE_PMC->PMC_MOR = (0x37 << 16) | BOARD_OSCOUNT | AT91C_CKGR_MOSCRCEN | AT91C_CKGR_MOSCXTEN | AT91C_CKGR_MOSCSEL;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
AT91C_BASE_PMC->PMC_MCKR = (AT91C_BASE_PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
|
||||
// initialize PLLA
|
||||
AT91C_BASE_PMC->PMC_PLLAR = BOARD_PLLR;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
|
||||
// initialize UTMI for USB usage
|
||||
AT91C_BASE_CKGR->CKGR_UCKR |= (AT91C_CKGR_UPLLCOUNT & (3 << 20)) | AT91C_CKGR_UPLLEN;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKU) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
|
||||
// switch to fast clock
|
||||
AT91C_BASE_PMC->PMC_MCKR = (BOARD_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
AT91C_BASE_PMC->PMC_MCKR = BOARD_MCKR;
|
||||
timeout = 0;
|
||||
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (timeout++ < CLOCK_TIMEOUT))
|
||||
;
|
||||
|
||||
// Optimize CPU setting for speed, for engineering samples only
|
||||
setDefaultMaster(1);
|
||||
|
||||
// Configure baud rate
|
||||
AT91C_BASE_DBGU->DBGU_BRGR = BOARD_MCK / (115200 * 16);
|
||||
}
|
||||
|
||||
static void initRAM(void)
|
||||
{
|
||||
const u32* src;
|
||||
u32* dest;
|
||||
|
||||
// copy initialized data from flash to RAM
|
||||
src = &_efixed;
|
||||
dest = &_srelocate;
|
||||
if(src != dest) {
|
||||
while(dest < &_erelocate)
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
// zero fill bss
|
||||
for(dest = &_szero; dest < &_ezero; dest++)
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void resetHandler(void)
|
||||
{
|
||||
for(u32* ptr = (u32*)0x20000000; ptr < (u32*)0x20007ff8; ptr++)
|
||||
*ptr = 0;
|
||||
for(u32* ptr = (u32*)0x20080000; ptr < (u32*)0x20084000; ptr++)
|
||||
*ptr = 0;
|
||||
|
||||
preInit();
|
||||
putCharDirect('0');
|
||||
|
||||
// disable all interrupts
|
||||
for(int i = 0; i < 8; i++)
|
||||
NVIC->ICER[i] = 0xffffffff;
|
||||
|
||||
putStrDirect("preinit...");
|
||||
led_configure();
|
||||
putCharDirect('1');
|
||||
led_internalSet(True);
|
||||
putCharDirect('2');
|
||||
startApplication();
|
||||
putCharDirect('3');
|
||||
led_internalSet(False);
|
||||
putCharDirect('4');
|
||||
lowLevelInit();
|
||||
putCharDirect('5');
|
||||
initRAM();
|
||||
putStrDirect("6...");
|
||||
putCharDirect('\r');
|
||||
putCharDirect('\n');
|
||||
|
||||
// configure interrupt vector table
|
||||
AT91C_BASE_NVIC->NVIC_VTOFFR = ((u32)(&interrupt_table));
|
||||
|
||||
// ready to go...
|
||||
__enable_fault_irq();
|
||||
__enable_irq();
|
||||
main();
|
||||
__disable_irq();
|
||||
__disable_fault_irq();
|
||||
|
||||
// yeppa...
|
||||
while(1)
|
||||
;
|
||||
|
||||
#if 0
|
||||
#ifdef BOARD_DFU_BTN_PIOA
|
||||
/* There is a PIO button that can be used to enter DFU */
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;
|
||||
AT91C_BASE_PIOA->PIO_PPUER = (1 << BOARD_DFU_BTN_PIOA);
|
||||
AT91C_BASE_PIOA->PIO_ODR = (1 << BOARD_DFU_BTN_PIOA);
|
||||
AT91C_BASE_PIOA->PIO_PER = (1 << BOARD_DFU_BTN_PIOA);
|
||||
|
||||
if (AT91C_BASE_PIOA->PIO_PDSR & (1 << BOARD_DFU_BTN_PIOA) &&
|
||||
#else /* BOARD_DFU_BTN_PIOA */
|
||||
if (1 &&
|
||||
#endif /* BOARD_DFU_BTN_PIOA */
|
||||
*((unsigned long *)USB_DFU_MAGIC_ADDR) != USB_DFU_MAGIC) {
|
||||
BootIntoApp();
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* This file uses lots of code from the Atmel reference library:
|
||||
* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 "descriptors.h"
|
||||
|
||||
void usbConfigurationDescriptor_Parse(
|
||||
const USBConfigurationDescriptor* configuration,
|
||||
USBInterfaceDescriptor** interfaces,
|
||||
USBEndpointDescriptor** endpoints,
|
||||
USBGenericDescriptor** others)
|
||||
{
|
||||
// Get size of configuration to parse
|
||||
int size = usbConfigurationDescriptor_GetTotalLength(configuration);
|
||||
size -= sizeof(USBConfigurationDescriptor);
|
||||
|
||||
// Start parsing descriptors
|
||||
USBGenericDescriptor *descriptor = (USBGenericDescriptor *)configuration;
|
||||
while(size > 0) {
|
||||
// Get next descriptor
|
||||
descriptor = usbGenericDescriptor_GetNextDescriptor(descriptor);
|
||||
size -= usbGenericDescriptor_GetLength(descriptor);
|
||||
|
||||
// Store descriptor in correponding array
|
||||
if(usbGenericDescriptor_GetType(descriptor) == USBGenericDescriptor_INTERFACE) {
|
||||
if(interfaces) {
|
||||
*interfaces = (USBInterfaceDescriptor*)descriptor;
|
||||
interfaces++;
|
||||
}
|
||||
} else if(usbGenericDescriptor_GetType(descriptor) == USBGenericDescriptor_ENDPOINT) {
|
||||
if(endpoints) {
|
||||
*endpoints = (USBEndpointDescriptor *)descriptor;
|
||||
endpoints++;
|
||||
}
|
||||
} else if(others) {
|
||||
*others = descriptor;
|
||||
others++;
|
||||
}
|
||||
}
|
||||
|
||||
// Null-terminate arrays
|
||||
if(interfaces) {
|
||||
*interfaces = 0;
|
||||
}
|
||||
if(endpoints) {
|
||||
*endpoints = 0;
|
||||
}
|
||||
if(others) {
|
||||
*others = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
#ifndef INCLUDE_DESCRIPTORS_H
|
||||
#define INCLUDE_DESCRIPTORS_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
|
||||
/// The device supports USB 2.00.
|
||||
#define USBDeviceDescriptor_USB2_00 0x0200
|
||||
|
||||
/// Device descriptor type.
|
||||
#define USBGenericDescriptor_DEVICE 1
|
||||
/// Configuration descriptor type.
|
||||
#define USBGenericDescriptor_CONFIGURATION 2
|
||||
/// String descriptor type.
|
||||
#define USBGenericDescriptor_STRING 3
|
||||
/// Interface descriptor type.
|
||||
#define USBGenericDescriptor_INTERFACE 4
|
||||
/// Endpoint descriptor type.
|
||||
#define USBGenericDescriptor_ENDPOINT 5
|
||||
/// Device qualifier descriptor type.
|
||||
#define USBGenericDescriptor_DEVICEQUALIFIER 6
|
||||
/// Other speed configuration descriptor type.
|
||||
#define USBGenericDescriptor_OTHERSPEEDCONFIGURATION 7
|
||||
/// Interface power descriptor type.
|
||||
#define USBGenericDescriptor_INTERFACEPOWER 8
|
||||
/// On-The-Go descriptor type.
|
||||
#define USBGenericDescriptor_OTG 9
|
||||
/// Debug descriptor type.
|
||||
#define USBGenericDescriptor_DEBUG 10
|
||||
/// Interface association descriptor type.
|
||||
#define USBGenericDescriptor_INTERFACEASSOCIATION 11
|
||||
|
||||
/// DFU function descriptor
|
||||
#define USBFunctionDescriptor_DFU 33
|
||||
|
||||
/// Device is self-powered and supports remote wake-up.
|
||||
#define USBConfigurationDescriptor_SELFPOWERED_RWAKEUP 0xe0
|
||||
|
||||
/// Control endpoint type.
|
||||
#define USBEndpointDescriptor_CONTROL 0
|
||||
/// Isochronous endpoint type.
|
||||
#define USBEndpointDescriptor_ISOCHRONOUS 1
|
||||
/// Bulk endpoint type.
|
||||
#define USBEndpointDescriptor_BULK 2
|
||||
/// Interrupt endpoint type.
|
||||
#define USBEndpointDescriptor_INTERRUPT 3
|
||||
|
||||
/// Endpoint receives data from the host.
|
||||
#define USBEndpointDescriptor_OUT 0
|
||||
/// Endpoint sends data to the host.
|
||||
#define USBEndpointDescriptor_IN 1
|
||||
|
||||
|
||||
/// Request is standard.
|
||||
#define USBGenericRequest_STANDARD 0
|
||||
/// Request is class-specific.
|
||||
#define USBGenericRequest_CLASS 1
|
||||
/// Request is vendor-specific.
|
||||
#define USBGenericRequest_VENDOR 2
|
||||
/// Recipient is the whole device.
|
||||
#define USBGenericRequest_DEVICE 0
|
||||
/// Recipient is an interface.
|
||||
#define USBGenericRequest_INTERFACE 1
|
||||
/// Recipient is an endpoint.
|
||||
#define USBGenericRequest_ENDPOINT 2
|
||||
/// Recipient is another entity.
|
||||
#define USBGenericRequest_OTHER 3
|
||||
|
||||
/// GET_STATUS request code.
|
||||
#define USBGenericRequest_GETSTATUS 0
|
||||
/// CLEAR_FEATURE request code.
|
||||
#define USBGenericRequest_CLEARFEATURE 1
|
||||
/// SET_FEATURE request code.
|
||||
#define USBGenericRequest_SETFEATURE 3
|
||||
/// SET_ADDRESS request code.
|
||||
#define USBGenericRequest_SETADDRESS 5
|
||||
/// GET_DESCRIPTOR request code.
|
||||
#define USBGenericRequest_GETDESCRIPTOR 6
|
||||
/// SET_DESCRIPTOR request code.
|
||||
#define USBGenericRequest_SETDESCRIPTOR 7
|
||||
/// GET_CONFIGURATION request code.
|
||||
#define USBGenericRequest_GETCONFIGURATION 8
|
||||
/// SET_CONFIGURATION request code.
|
||||
#define USBGenericRequest_SETCONFIGURATION 9
|
||||
/// GET_INTERFACE request code.
|
||||
#define USBGenericRequest_GETINTERFACE 10
|
||||
/// SET_INTERFACE request code.
|
||||
#define USBGenericRequest_SETINTERFACE 11
|
||||
/// SYNCH_FRAME request code.
|
||||
#define USBGenericRequest_SYNCHFRAME 12
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
} __attribute__((packed)) USBGenericDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 bcdUSB;
|
||||
u8 bDeviceClass;
|
||||
u8 bDeviceSubClass;
|
||||
u8 bDeviceProtocol;
|
||||
u8 bMaxPacketSize0;
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
u16 bcdDevice;
|
||||
u8 iManufacturer;
|
||||
u8 iProduct;
|
||||
u8 iSerialNumber;
|
||||
u8 bNumConfigurations;
|
||||
} __attribute__((packed)) USBDeviceDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 wTotalLength;
|
||||
u8 bNumInterfaces;
|
||||
u8 bConfigurationValue;
|
||||
u8 iConfiguration;
|
||||
u8 bmAttributes;
|
||||
u8 bMaxPower;
|
||||
} __attribute__((packed)) USBConfigurationDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u16 bcdUSB;
|
||||
u8 bDeviceClass;
|
||||
u8 bDeviceSubClass;
|
||||
u8 bDeviceProtocol;
|
||||
u8 bMaxPacketSize0;
|
||||
u8 bNumConfigurations;
|
||||
u8 bReserved;
|
||||
} __attribute__((packed)) USBDeviceQualifierDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bInterfaceNumber;
|
||||
u8 bAlternateSetting;
|
||||
u8 bNumEndpoints;
|
||||
u8 bInterfaceClass;
|
||||
u8 bInterfaceSubClass;
|
||||
u8 bInterfaceProtocol;
|
||||
u8 iInterface;
|
||||
} __attribute__((packed)) USBInterfaceDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bLength;
|
||||
u8 bDescriptorType;
|
||||
u8 bEndpointAddress;
|
||||
u8 bmAttributes;
|
||||
u16 wMaxPacketSize;
|
||||
u8 bInterval;
|
||||
}__attribute__((packed)) USBEndpointDescriptor;
|
||||
|
||||
typedef struct {
|
||||
u8 bmRequestType;
|
||||
u8 bRequest;
|
||||
u16 wValue;
|
||||
u16 wIndex;
|
||||
u16 wLength;
|
||||
} __attribute__((packed)) USBGenericRequest;
|
||||
|
||||
// generic descriptor
|
||||
|
||||
inline u16 usbGenericDescriptor_GetLength(const USBGenericDescriptor* descriptor)
|
||||
{
|
||||
return descriptor->bLength;
|
||||
}
|
||||
|
||||
inline u8 usbGenericDescriptor_GetType(const USBGenericDescriptor* descriptor)
|
||||
{
|
||||
return descriptor->bDescriptorType;
|
||||
}
|
||||
|
||||
inline USBGenericDescriptor* usbGenericDescriptor_GetNextDescriptor(const USBGenericDescriptor* descriptor)
|
||||
{
|
||||
return (USBGenericDescriptor*)(((u8*)descriptor) + usbGenericDescriptor_GetLength(descriptor));
|
||||
}
|
||||
|
||||
// configuration descriptor
|
||||
|
||||
inline uint usbConfigurationDescriptor_GetTotalLength(const USBConfigurationDescriptor* configuration)
|
||||
{
|
||||
return configuration->wTotalLength;
|
||||
}
|
||||
|
||||
inline u8 usbConfigurationDescriptor_IsSelfPowered(const USBConfigurationDescriptor* configuration)
|
||||
{
|
||||
if((configuration->bmAttributes & (1 << 6)) != 0)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void usbConfigurationDescriptor_Parse(
|
||||
const USBConfigurationDescriptor* configuration,
|
||||
USBInterfaceDescriptor** interfaces,
|
||||
USBEndpointDescriptor** endpoints,
|
||||
USBGenericDescriptor** others);
|
||||
|
||||
// endpoint descriptor
|
||||
|
||||
inline u8 usbEndpointDescriptor_GetNumber(const USBEndpointDescriptor* endpoint)
|
||||
{
|
||||
return endpoint->bEndpointAddress & 0x0f;
|
||||
}
|
||||
|
||||
inline u8 usbEndpointDescriptor_GetType(const USBEndpointDescriptor* endpoint)
|
||||
{
|
||||
return endpoint->bmAttributes & 0x03;
|
||||
}
|
||||
|
||||
inline u8 usbEndpointDescriptor_GetDirection(const USBEndpointDescriptor* endpoint)
|
||||
{
|
||||
if((endpoint->bEndpointAddress & 0x80) != 0) {
|
||||
return USBEndpointDescriptor_IN;
|
||||
} else {
|
||||
return USBEndpointDescriptor_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
inline u16 usbEndpointDescriptor_GetMaxPacketSize(const USBEndpointDescriptor *endpoint)
|
||||
{
|
||||
return endpoint->wMaxPacketSize;
|
||||
}
|
||||
|
||||
// generic request
|
||||
|
||||
inline u8 usbGenericRequest_GetType(const USBGenericRequest* request)
|
||||
{
|
||||
return ((request->bmRequestType >> 5) & 0x3);
|
||||
}
|
||||
|
||||
inline u8 usbGenericRequest_GetRecipient(const USBGenericRequest* request)
|
||||
{
|
||||
return request->bmRequestType & 0xf;
|
||||
}
|
||||
|
||||
inline u8 usbGenericRequest_GetRequest(const USBGenericRequest* request)
|
||||
{
|
||||
return request->bRequest;
|
||||
}
|
||||
|
||||
inline u16 usbGenericRequest_GetValue(const USBGenericRequest* request)
|
||||
{
|
||||
return request->wValue;
|
||||
}
|
||||
|
||||
inline u16 usbGenericRequest_GetLength(const USBGenericRequest* request)
|
||||
{
|
||||
return request->wLength;
|
||||
}
|
||||
|
||||
inline u16 usbGenericRequest_GetIndex(const USBGenericRequest* request)
|
||||
{
|
||||
return request->wIndex;
|
||||
}
|
||||
|
||||
inline u8 usbGenericRequest_GetEndpointNumber(const USBGenericRequest* request)
|
||||
{
|
||||
return usbGenericRequest_GetIndex(request) & 0x0f;
|
||||
}
|
||||
|
||||
// get descriptor request
|
||||
|
||||
inline u8 usbGetDescriptorRequest_GetDescriptorType(const USBGenericRequest* request)
|
||||
{
|
||||
return (usbGenericRequest_GetValue(request) >> 8) & 0xff;
|
||||
}
|
||||
|
||||
inline u8 usbGetDescriptorRequest_GetDescriptorIndex(const USBGenericRequest* request)
|
||||
{
|
||||
return usbGenericRequest_GetValue(request) & 0xff;
|
||||
}
|
||||
|
||||
// set address request
|
||||
|
||||
inline u8 usbSetAddressRequest_GetAddress(const USBGenericRequest* request)
|
||||
{
|
||||
return usbGenericRequest_GetValue(request) & 0x7f;
|
||||
}
|
||||
|
||||
// set configuration request
|
||||
|
||||
inline u8 usbSetConfigurationRequest_GetConfiguration(const USBGenericRequest* request)
|
||||
{
|
||||
return usbGenericRequest_GetValue(request);
|
||||
}
|
||||
|
||||
// interface request
|
||||
|
||||
inline u8 usbInterfaceRequest_GetInterface(const USBGenericRequest* request)
|
||||
{
|
||||
return (usbGenericRequest_GetIndex(request) & 0xff);
|
||||
}
|
||||
|
||||
inline u8 usbInterfaceRequest_GetAlternateSetting(const USBGenericRequest* request)
|
||||
{
|
||||
return (usbGenericRequest_GetValue(request) & 0xff);
|
||||
}
|
||||
|
||||
#endif // INCLUDE_DESCRIPTORS_H
|
|
@ -0,0 +1,226 @@
|
|||
/**************************************************************
|
||||
*
|
||||
* Lattice Semiconductor Corp. Copyright 2008
|
||||
*
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Revision History of hardware.c
|
||||
*
|
||||
*
|
||||
* 09/11/07 NN type cast all the mismatch variables
|
||||
***************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "opcode.h"
|
||||
#include "hardware.h"
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* EXTERNAL FUNCTION *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
extern void ispVMStateMachine( char a_cNextState );
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* READPORT *
|
||||
* *
|
||||
* INPUT: *
|
||||
* None. *
|
||||
* *
|
||||
* RETURN: *
|
||||
* Returns the bit read back from the device. *
|
||||
* *
|
||||
* DESCRIPTION: *
|
||||
* This function is used to read the TDO pin from the *
|
||||
* input port. *
|
||||
* *
|
||||
* NOTE: This function should be modified in an embedded *
|
||||
* system! *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
int readPort()
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = *((volatile uint32_t*)(0x400e0e00 + 0x3c));
|
||||
|
||||
if(value & (1 << 6))
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* WRITEPORT *
|
||||
* *
|
||||
* INPUT: *
|
||||
* a_ucPins: a byte to indicate which pin will be *
|
||||
* depending on the value. *
|
||||
* *
|
||||
* a_ucValue: the value to determine of the pin above *
|
||||
* will be written out or not. *
|
||||
* *
|
||||
* RETURN: *
|
||||
* None. *
|
||||
* *
|
||||
* DESCRIPTION: *
|
||||
* To apply the specified value to the pins indicated. *
|
||||
* This routine will likely be modified for specific *
|
||||
* systems. As an example, this code is for the PC, as *
|
||||
* described below. *
|
||||
* *
|
||||
* This routine uses the IBM-PC standard Parallel port, *
|
||||
* along with the schematic shown in Lattice *
|
||||
* documentation, to apply the signals to the programming *
|
||||
* loop. *
|
||||
* *
|
||||
* NOTE: This function should be modified in an embedded *
|
||||
* system! *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
void writePort( unsigned int a_ucPins, unsigned int a_ucValue )
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
if(a_ucPins & pinTDI)
|
||||
value |= (1 << 8);
|
||||
if(a_ucPins & pinTCK)
|
||||
value |= (1 << 7);
|
||||
if(a_ucPins & pinTMS)
|
||||
value |= (1 << 5);
|
||||
|
||||
if(a_ucValue)
|
||||
*((volatile uint32_t*)(0x400e0e00 + 0x30)) = value;
|
||||
else *((volatile uint32_t*)(0x400e0e00 + 0x34)) = value;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* ISPVMDELAY *
|
||||
* *
|
||||
* INPUT: *
|
||||
* a_uiDelay: delay in milliseconds *
|
||||
* *
|
||||
* RETURN: *
|
||||
* None. *
|
||||
* *
|
||||
* DESCRIPTION: *
|
||||
* The user must implement a delay to observe a_uiDelay, *
|
||||
* where a_uiDelay is the number of milliseconds that must *
|
||||
* pass before data is read from in_port. Since platforms and*
|
||||
* processor speeds vary greatly, this task is left to the *
|
||||
* user. This subroutine is called upon to provide a delay *
|
||||
* from 1 millisecond to a few hundreds milliseconds each time*
|
||||
* That is the reason behind using unsigned long integer in *
|
||||
* this subroutine. It is OK to provide longer delay than *
|
||||
* required. It is not acceptable if the delay is shorter than*
|
||||
* required. *
|
||||
* *
|
||||
* Note: user must re - implement to target specific hardware.*
|
||||
* *
|
||||
* Example: Use the for loop to create the microsecond delay. *
|
||||
* Loop 1K times to produce the milliseconds delay. *
|
||||
* *
|
||||
* Let the CPU clock (system clock) be F Mhz. *
|
||||
* *
|
||||
* Let the for loop represented by the 2 lines of *
|
||||
* machine code: *
|
||||
* LOOP: DEC RA; *
|
||||
* JNZ LOOP; *
|
||||
* Let the for loop number for one microsecond be L. *
|
||||
* Lets assume 4 system clocks for each line of *
|
||||
* machine code. *
|
||||
* Then 1 us = 1/F (microseconds per clock) *
|
||||
* x (2 lines) x (4 clocks per line) x L*
|
||||
* = 8L/F *
|
||||
* Or L = F/8; *
|
||||
* *
|
||||
* Convert the unit in microseconds to *
|
||||
* milliseconds. *
|
||||
* L = F/8 x 1000; *
|
||||
* Lets assume the CPU clock is set to 48MHZ. The C *
|
||||
* code then is: *
|
||||
* *
|
||||
* unsigned int F = 48; //MHZ. *
|
||||
* unsigned int L = F/8; //microseconds. *
|
||||
* unsigned int index, m; *
|
||||
* *
|
||||
* *
|
||||
* if (L < 1) L = 1; //minimum is i microsecond. *
|
||||
* for (index=0; index < a_uiDelay * L; index++) *
|
||||
* { *
|
||||
* //loop 1K times to produce milliseconds delay *
|
||||
* for (m=0; m<1000; m++); //milliseconds *
|
||||
* } *
|
||||
* return 0; *
|
||||
* *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
/* the unit of a_uiDelay is milliseconds */
|
||||
void ispVMDelay( unsigned int a_uiDelay )
|
||||
{
|
||||
// yes, this is more or less calibrated - cd
|
||||
volatile int i, j;
|
||||
for(i = 0; i < a_uiDelay; i++) {
|
||||
for(j = 0; j < 5000; j++)
|
||||
asm("nop");
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* ENABLEHARDWARE *
|
||||
* *
|
||||
* INPUT: *
|
||||
* None. *
|
||||
* *
|
||||
* RETURN: *
|
||||
* None. *
|
||||
* *
|
||||
* DESCRIPTION: *
|
||||
* This function is called to enable the hardware. *
|
||||
* *
|
||||
* NOTE: This function should be modified in an embedded *
|
||||
* system! *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
void EnableHardware()
|
||||
{
|
||||
ispVMStateMachine(RESET);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* DISABLEHARDWARE *
|
||||
* *
|
||||
* INPUT: *
|
||||
* None. *
|
||||
* *
|
||||
* RETURN: *
|
||||
* None. *
|
||||
* *
|
||||
* DESCRIPTION: *
|
||||
* This function is called to disable the hardware. *
|
||||
* *
|
||||
* NOTE: This function should be modified in an embedded *
|
||||
* system! *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
void DisableHardware()
|
||||
{
|
||||
ispVMStateMachine(RESET);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef INCLUDE_HARDWARE_H
|
||||
#define INCLUDE_HARDWARE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../crt/types.h"
|
||||
|
||||
const uint8_t* g_ispAlgo;
|
||||
size_t g_ispAlgoSize;
|
||||
const uint8_t* g_ispData;
|
||||
size_t g_ispDataSize;
|
||||
|
||||
#endif // INCLUDE_HARDWARE_H
|
|
@ -0,0 +1,135 @@
|
|||
|
||||
/**************************************************************
|
||||
*
|
||||
* Revision History of opcode.h
|
||||
*
|
||||
*
|
||||
* 09/11/07 NN Updated to support version 1.3
|
||||
* This version supported new POLING STATUS LOOP opcodes
|
||||
* for Flash programming of the Lattice FPGA devices
|
||||
* #define LOOP = 0x58
|
||||
* #define ENDLOOP = 0x59
|
||||
***************************************************************/
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* LATTICE CABLE DEFINTIONS. *
|
||||
* *
|
||||
* Define these only if the lattice cable is being used. *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define pinTDI 1
|
||||
#define pinTCK 2
|
||||
#define pinTMS 4
|
||||
#define pinENABLE 8
|
||||
#define pinTRST 16
|
||||
#define pinCE 32
|
||||
#define pinTDO 64
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* ERROR DEFINITIONS *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define ERR_VERIFY_FAIL -1
|
||||
#define ERR_FIND_ALGO_FILE -2
|
||||
#define ERR_FIND_DATA_FILE -3
|
||||
#define ERR_WRONG_VERSION -4
|
||||
#define ERR_ALGO_FILE_ERROR -5
|
||||
#define ERR_DATA_FILE_ERROR -6
|
||||
#define ERR_OUT_OF_MEMORY -7
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* DATA TYPE REGISTER BIT DEFINITIONS *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define SIR_DATA 0x0001 /*** Current command is SIR ***/
|
||||
#define SDR_DATA 0x0002 /*** Current command is SDR ***/
|
||||
#define TDI_DATA 0x0004 /*** Command contains TDI ***/
|
||||
#define TDO_DATA 0x0008 /*** Command contains TDO ***/
|
||||
#define MASK_DATA 0x0010 /*** Command contains MASK ***/
|
||||
#define DTDI_DATA 0x0020 /*** Verification flow ***/
|
||||
#define DTDO_DATA 0x0040 /*** Verification flow ***/
|
||||
#define COMPRESS 0x0080 /*** Compressed data file ***/
|
||||
#define COMPRESS_FRAME 0x0100 /*** Compressed data frame ***/
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* USED JTAG STATE *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define RESET 0x00
|
||||
#define IDLE 0x01
|
||||
#define IRPAUSE 0x02
|
||||
#define DRPAUSE 0x03
|
||||
#define SHIFTIR 0x04
|
||||
#define SHIFTDR 0x05
|
||||
#define DRCAPTURE 0x06
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* VME OPCODE DEFINITIONS *
|
||||
* *
|
||||
* These are the opcodes found in the VME file. Although *
|
||||
* most of them are similar to SVF commands, a few opcodes *
|
||||
* are available only in VME format. *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define STATE 0x10
|
||||
#define SIR 0x11
|
||||
#define SDR 0x12
|
||||
#define TCK 0x1B
|
||||
#define WAIT 0x1A
|
||||
#define ENDDR 0x02
|
||||
#define ENDIR 0x03
|
||||
#define HIR 0x06
|
||||
#define TIR 0x07
|
||||
#define HDR 0x08
|
||||
#define TDR 0x09
|
||||
#define TDI 0x13
|
||||
#define CONTINUE 0x70
|
||||
#define TDO 0x14
|
||||
#define MASK 0x15
|
||||
#define LOOP 0x58
|
||||
#define ENDLOOP 0x59
|
||||
#define LCOUNT 0x66
|
||||
#define LDELAY 0x67
|
||||
#define LSDR 0x68
|
||||
#define ENDSTATE 0x69
|
||||
#define ENDVME 0x7F
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* Begin future opcodes at 0xA0 to avoid conflict with Full *
|
||||
* VME opcodes. *
|
||||
* *
|
||||
*************************************************************/
|
||||
|
||||
#define BEGIN_REPEAT 0xA0
|
||||
#define END_REPEAT 0xA1
|
||||
#define END_FRAME 0xA2
|
||||
#define DATA 0xA3
|
||||
#define PROGRAM 0xA4
|
||||
#define VERIFY 0xA5
|
||||
#define DTDI 0xA6
|
||||
#define DTDO 0xA7
|
||||
|
||||
/*************************************************************
|
||||
* *
|
||||
* Opcode for discrete pins toggling *
|
||||
* *
|
||||
*************************************************************/
|
||||
#define signalENABLE 0x1C /*assert the ispEN pin*/
|
||||
#define signalTMS 0x1D /*assert the MODE or TMS pin*/
|
||||
#define signalTCK 0x1E /*assert the SCLK or TCK pin*/
|
||||
#define signalTDI 0x1F /*assert the SDI or TDI pin*/
|
||||
#define signalTRST 0x20 /*assert the RESET or TRST pin*/
|
||||
#define signalTDO 0x21 /*assert the RESET or TDO pin*/
|
||||
#define signalCableEN 0x22 /*assert the RESET or CableEN pin*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,392 @@
|
|||
/* This file uses lots of code from the Atmel reference library:
|
||||
* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 <stddef.h>
|
||||
#include "usb.h"
|
||||
#include "usbdevice.h"
|
||||
#include "descriptors.h"
|
||||
#include "../crt/stdio.h"
|
||||
#include "../driver/usbdhs.h"
|
||||
#include "../board.h"
|
||||
|
||||
static void setInterface(u8 infnum, u8 setting)
|
||||
{
|
||||
// Make sure alternate settings are supported
|
||||
if(usbDevice.interfaces == NULL) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
// Change the current setting of the interface and trigger the callback
|
||||
// if necessary
|
||||
if(usbDevice.interfaces[infnum] != setting) {
|
||||
usbDevice.interfaces[infnum] = setting;
|
||||
//USBDDriverCallbacks_InterfaceSettingChanged(infnum, setting);
|
||||
}
|
||||
|
||||
// Acknowledge the request
|
||||
usbdhs_write(
|
||||
0, // Endpoint #0
|
||||
0, // No data buffer
|
||||
0, // No data buffer
|
||||
(TransferCallback)NULL,
|
||||
(void*)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void getInterface(u8 infnum)
|
||||
{
|
||||
// Make sure alternate settings are supported, or STALL the control pipe
|
||||
if(usbDevice.interfaces == NULL) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
// Sends the current interface setting to the host
|
||||
usbdhs_write(0, &(usbDevice.interfaces[infnum]), 1, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void sendDeviceStatus()
|
||||
{
|
||||
static u16 data = 0;
|
||||
const USBConfigurationDescriptor* configurationDescriptor;
|
||||
|
||||
// Use different configuration depending on device speed
|
||||
if(usbdhs_isHighSpeed())
|
||||
configurationDescriptor = usbDevice.hsConfigurationDescriptor;
|
||||
else configurationDescriptor = usbDevice.fsConfigurationDescriptor;
|
||||
|
||||
// Check current configuration for power mode (if device is configured)
|
||||
if(usbDevice.activeConfiguration != 0) {
|
||||
if(usbConfigurationDescriptor_IsSelfPowered(configurationDescriptor))
|
||||
data |= 1;
|
||||
}
|
||||
|
||||
// Check if remote wake-up is enabled
|
||||
if(usbDevice.remoteWakeupEnabled)
|
||||
data |= 2;
|
||||
|
||||
// Send the device status
|
||||
usbdhs_write(0, &data, 2, NULL, NULL);
|
||||
}
|
||||
|
||||
static void sendEndpointStatus(u8 endpoint)
|
||||
{
|
||||
static u16 data = 0;
|
||||
|
||||
// Check if the endpoint exists
|
||||
if(endpoint > CHIP_USB_NUMENDPOINTS) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
// Check if the endpoint if currently halted
|
||||
if(usbdhs_isHalted(endpoint))
|
||||
data |= 1;
|
||||
// Send the endpoint status
|
||||
usbdhs_write(0, &data, 2, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void setConfiguration(u8 cfgnum)
|
||||
{
|
||||
USBEndpointDescriptor* endpointDescriptor[CHIP_USB_NUMENDPOINTS + 1];
|
||||
const USBConfigurationDescriptor* configurationDescriptor;
|
||||
|
||||
// Use different descriptor depending on device speed
|
||||
if(usbdhs_isHighSpeed())
|
||||
configurationDescriptor = usbDevice.hsConfigurationDescriptor;
|
||||
else configurationDescriptor = usbDevice.fsConfigurationDescriptor;
|
||||
|
||||
// Set & save the desired configuration
|
||||
usbdhs_setConfiguration(cfgnum);
|
||||
usbDevice.activeConfiguration = cfgnum;
|
||||
|
||||
// If the configuration is not 0, configure endpoints
|
||||
if(cfgnum != 0) {
|
||||
// Parse configuration to get endpoint descriptors
|
||||
usbConfigurationDescriptor_Parse(configurationDescriptor, 0, endpointDescriptor, 0);
|
||||
|
||||
// Configure endpoints
|
||||
for(int i = 0; endpointDescriptor[i] != 0; i++)
|
||||
usbdhs_configureEndpoint(endpointDescriptor[i]);
|
||||
}
|
||||
// Should be done before send the ZLP
|
||||
//USBDDriverCallbacks_ConfigurationChanged(cfgnum);
|
||||
|
||||
// Acknowledge the request
|
||||
usbdhs_write(
|
||||
0, // Endpoint #0
|
||||
0, // No data buffer
|
||||
0, // No data buffer
|
||||
(TransferCallback)NULL,
|
||||
(void*)NULL);
|
||||
}
|
||||
|
||||
static void sendDescriptor(u32 type, u32 indexRDesc, u32 length)
|
||||
{
|
||||
const USBDeviceDescriptor* deviceDescriptor;
|
||||
const USBConfigurationDescriptor* configurationDescriptor;
|
||||
const USBDeviceQualifierDescriptor* deviceQualifierDescriptor;;
|
||||
const USBConfigurationDescriptor* otherSpeedDescriptor;
|
||||
Bool terminateWithNull = False;
|
||||
const USBGenericDescriptor** strings = (const USBGenericDescriptor**)usbDevice.strings;
|
||||
const USBGenericDescriptor* string;
|
||||
|
||||
if(usbdhs_isHighSpeed()) {
|
||||
//dprintf("HS");
|
||||
deviceDescriptor = usbDevice.hsDeviceDescriptor;
|
||||
configurationDescriptor = usbDevice.hsConfigurationDescriptor;
|
||||
deviceQualifierDescriptor = usbDevice.hsQualifierDescriptor;
|
||||
otherSpeedDescriptor = usbDevice.hsOtherSpeedDescriptor;
|
||||
} else {
|
||||
//dprintf("FS");
|
||||
deviceDescriptor = usbDevice.fsDeviceDescriptor;
|
||||
configurationDescriptor = usbDevice.fsConfigurationDescriptor;
|
||||
deviceQualifierDescriptor = usbDevice.fsQualifierDescriptor;
|
||||
otherSpeedDescriptor = usbDevice.fsOtherSpeedDescriptor;
|
||||
}
|
||||
|
||||
// Check the descriptor type
|
||||
switch(type) {
|
||||
case USBGenericDescriptor_DEVICE:
|
||||
if(length > usbGenericDescriptor_GetLength((USBGenericDescriptor*)deviceDescriptor))
|
||||
length = usbGenericDescriptor_GetLength((USBGenericDescriptor*)deviceDescriptor);
|
||||
usbdhs_write(0, deviceDescriptor, length, NULL, NULL);
|
||||
break;
|
||||
|
||||
case USBGenericDescriptor_CONFIGURATION:
|
||||
// Adjust length and send descriptor
|
||||
if(length > usbConfigurationDescriptor_GetTotalLength(configurationDescriptor)) {
|
||||
length = usbConfigurationDescriptor_GetTotalLength(configurationDescriptor);
|
||||
terminateWithNull = ((length % deviceDescriptor->bMaxPacketSize0) == 0) ? True : False;
|
||||
}
|
||||
usbdhs_write(0, configurationDescriptor, length, terminateWithNull ? usbCtrlSendNull : NULL, NULL);
|
||||
break;
|
||||
|
||||
case USBGenericDescriptor_DEVICEQUALIFIER:
|
||||
if(deviceQualifierDescriptor == NULL) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
if(length > usbGenericDescriptor_GetLength((USBGenericDescriptor*)deviceQualifierDescriptor))
|
||||
length = usbGenericDescriptor_GetLength((USBGenericDescriptor*)deviceQualifierDescriptor);
|
||||
usbdhs_write(0, deviceQualifierDescriptor, length, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBGenericDescriptor_OTHERSPEEDCONFIGURATION:
|
||||
if(otherSpeedDescriptor == NULL) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
// Adjust length and send descriptor
|
||||
if(length > usbConfigurationDescriptor_GetTotalLength(otherSpeedDescriptor)) {
|
||||
length = usbConfigurationDescriptor_GetTotalLength(otherSpeedDescriptor);
|
||||
terminateWithNull = ((length % deviceDescriptor->bMaxPacketSize0) == 0);
|
||||
}
|
||||
usbdhs_write(0, otherSpeedDescriptor, length, terminateWithNull ? usbCtrlSendNull : NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBGenericDescriptor_STRING:
|
||||
// Check if descriptor exists
|
||||
if((indexRDesc > usbDevice.numStrings) || (strings[indexRDesc] == NULL)) {
|
||||
usbdhs_stall(0);
|
||||
} else {
|
||||
string = strings[indexRDesc];
|
||||
// Adjust length and send descriptor
|
||||
if(length > usbGenericDescriptor_GetLength(string)) {
|
||||
length = usbGenericDescriptor_GetLength(string);
|
||||
terminateWithNull = ((length % deviceDescriptor->bMaxPacketSize0) == 0);
|
||||
}
|
||||
usbdhs_write(0, string, length, terminateWithNull ? usbCtrlSendNull : NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
usbdhs_stall(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbGenericRequestHandler(const USBGenericRequest* request)
|
||||
{
|
||||
unsigned char cfgnum;
|
||||
unsigned char infnum;
|
||||
unsigned char eptnum;
|
||||
unsigned char setting;
|
||||
u32 type;
|
||||
u32 indexDesc;
|
||||
u32 length;
|
||||
u32 address;
|
||||
|
||||
// Check request code
|
||||
switch(usbGenericRequest_GetRequest(request)) {
|
||||
|
||||
case USBGenericRequest_GETDESCRIPTOR:
|
||||
// Send the requested descriptor
|
||||
type = usbGetDescriptorRequest_GetDescriptorType(request);
|
||||
indexDesc = usbGetDescriptorRequest_GetDescriptorIndex(request);
|
||||
length = usbGenericRequest_GetLength(request);
|
||||
sendDescriptor(type, indexDesc, length);
|
||||
break;
|
||||
|
||||
case USBGenericRequest_SETADDRESS:
|
||||
// Sends a zero-length packet and then set the device address
|
||||
address = usbSetAddressRequest_GetAddress(request);
|
||||
usbdhs_write(0, NULL, 0, (TransferCallback)usbdhs_setAddress, (void*)address);
|
||||
break;
|
||||
|
||||
case USBGenericRequest_SETCONFIGURATION:
|
||||
// Set the requested configuration
|
||||
cfgnum = usbSetConfigurationRequest_GetConfiguration(request);
|
||||
setConfiguration(cfgnum);
|
||||
break;
|
||||
|
||||
case USBGenericRequest_GETSTATUS:
|
||||
// Check who is the recipient
|
||||
switch(usbGenericRequest_GetRecipient(request)) {
|
||||
case USBGenericRequest_DEVICE:
|
||||
// Send the device status
|
||||
sendDeviceStatus();
|
||||
break;
|
||||
|
||||
case USBGenericRequest_ENDPOINT:
|
||||
// Send the endpoint status
|
||||
eptnum = usbGenericRequest_GetEndpointNumber(request);
|
||||
sendEndpointStatus(eptnum);
|
||||
break;
|
||||
|
||||
default:
|
||||
usbdhs_stall(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBGenericRequest_SETINTERFACE:
|
||||
infnum = usbInterfaceRequest_GetInterface(request);
|
||||
setting = usbInterfaceRequest_GetAlternateSetting(request);
|
||||
setInterface(infnum, setting);
|
||||
break;
|
||||
|
||||
case USBGenericRequest_GETINTERFACE:
|
||||
infnum = usbInterfaceRequest_GetInterface(request);
|
||||
getInterface(infnum);
|
||||
break;
|
||||
|
||||
|
||||
#if 0
|
||||
case USBGenericRequest_GETCONFIGURATION:
|
||||
TRACE_INFO_WP("gCfg ");
|
||||
|
||||
// Send the current configuration number
|
||||
GetConfiguration(pDriver);
|
||||
break;
|
||||
|
||||
case USBGenericRequest_CLEARFEATURE:
|
||||
TRACE_INFO_WP("cFeat ");
|
||||
|
||||
// Check which is the requested feature
|
||||
switch(USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
||||
|
||||
case USBFeatureRequest_ENDPOINTHALT:
|
||||
TRACE_INFO_WP("Hlt ");
|
||||
|
||||
// Unhalt endpoint and send a zero-length packet
|
||||
USBD_Unhalt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
||||
TRACE_INFO_WP("RmWU ");
|
||||
|
||||
// Disable remote wake-up and send a zero-length packet
|
||||
pDriver->isRemoteWakeUpEnabled = 0;
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE_WARNING("USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest));
|
||||
USBD_Stall(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBGenericRequest_SETFEATURE:
|
||||
TRACE_INFO_WP("sFeat ");
|
||||
|
||||
// Check which is the selected feature
|
||||
switch(USBFeatureRequest_GetFeatureSelector(pRequest)) {
|
||||
|
||||
case USBFeatureRequest_DEVICEREMOTEWAKEUP:
|
||||
TRACE_INFO_WP("RmWU ");
|
||||
|
||||
// Enable remote wake-up and send a ZLP
|
||||
pDriver->isRemoteWakeUpEnabled = 1;
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case USBFeatureRequest_ENDPOINTHALT:
|
||||
TRACE_INFO_WP("Halt ");
|
||||
// Halt endpoint
|
||||
USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case USBFeatureRequest_TESTMODE:
|
||||
// 7.1.20 Test Mode Support, 9.4.9 SetFeature
|
||||
if ((USBGenericRequest_GetRecipient(pRequest) == USBGenericRequest_DEVICE)
|
||||
&& ((USBGenericRequest_GetIndex(pRequest) & 0x000F) == 0)) {
|
||||
|
||||
// Handle test request
|
||||
USBDDriver_Test(USBFeatureRequest_GetTestSelector(pRequest));
|
||||
}
|
||||
else {
|
||||
|
||||
USBD_Stall(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE_WARNING("USBDDriver_RequestHandler: Unknown feature selector (%d)\n\r", USBFeatureRequest_GetFeatureSelector(pRequest));
|
||||
USBD_Stall(0);
|
||||
}
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
dprintf("USBDDriver_RequestHandler: Unknown request code (%d)\n\r", usbGenericRequest_GetRequest(request));
|
||||
usbdhs_stall(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbCtrlSendNull(void* arg, u8 status, uint transferred, uint remaining)
|
||||
{
|
||||
usbdhs_write(
|
||||
0, // Endpoint #0
|
||||
0, // No data buffer
|
||||
0, // No data buffer
|
||||
(TransferCallback)NULL,
|
||||
(void*)NULL);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef INCLUDE_USB_H
|
||||
#define INCLUDE_USB_H
|
||||
|
||||
#include "usb.h"
|
||||
#include "descriptors.h"
|
||||
|
||||
void usbGenericRequestHandler(const USBGenericRequest* request);
|
||||
void usbCtrlSendNull(void* arg, u8 status, uint transferred, uint remaining);
|
||||
|
||||
#endif // INCLUDE_USB_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
|||
#ifndef INCLUDE_USBDEVICE_H
|
||||
#define INCLUDE_USBDEVICE_H
|
||||
|
||||
#include "../crt/types.h"
|
||||
#include "usb.h"
|
||||
|
||||
typedef struct USBDevice_ {
|
||||
const USBDeviceDescriptor* fsDeviceDescriptor;
|
||||
const USBConfigurationDescriptor* fsConfigurationDescriptor;
|
||||
const USBDeviceQualifierDescriptor* fsQualifierDescriptor;
|
||||
const USBConfigurationDescriptor* fsOtherSpeedDescriptor;
|
||||
|
||||
const USBDeviceDescriptor* hsDeviceDescriptor;
|
||||
const USBConfigurationDescriptor* hsConfigurationDescriptor;
|
||||
const USBDeviceQualifierDescriptor* hsQualifierDescriptor;
|
||||
const USBConfigurationDescriptor* hsOtherSpeedDescriptor;
|
||||
|
||||
const u8** strings;
|
||||
uint numStrings;
|
||||
|
||||
uint activeConfiguration;
|
||||
Bool remoteWakeupEnabled;
|
||||
u8* interfaces;
|
||||
} USBDevice;
|
||||
|
||||
extern USBDevice usbDevice;
|
||||
|
||||
void usbDevice_configure(void);
|
||||
void usbDevice_setSerial(const char* sn);
|
||||
|
||||
void usbRequestReceived(const USBGenericRequest* request);
|
||||
|
||||
void usbDevice_tick(void);
|
||||
|
||||
#endif // INCLUDE_USBDEVICE_H
|
|
@ -0,0 +1,421 @@
|
|||
/* This file uses lots of code from the Atmel reference library:
|
||||
* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 "at91sam3u4/AT91SAM3U4.h"
|
||||
#include "board.h"
|
||||
#include "at91sam3u4/core_cm3.h"
|
||||
#include "vectors.h"
|
||||
#include "crt/types.h"
|
||||
#include "crt/stdio.h"
|
||||
|
||||
// stack top
|
||||
extern const u32 _estack;
|
||||
|
||||
// dummy handlers - remove from here when used for real
|
||||
static void nmiHandler(void);
|
||||
static void hardFaultHandler(void);
|
||||
static void memManagerHandler(void);
|
||||
static void busFaultHandler(void);
|
||||
static void usageFaultHandler(void);
|
||||
static void svcHandler(void);
|
||||
static void debugMonHandler(void);
|
||||
static void pendSVHandler(void);
|
||||
static void sysTickHandler(void);
|
||||
static void supcIrqHandler(void);
|
||||
static void rstcIrqHandler(void);
|
||||
static void rtcIrqHandler(void);
|
||||
static void rttIrqHandler(void);
|
||||
static void wdtIrqHandler(void);
|
||||
static void pmcIrqHandler(void);
|
||||
static void efc0IrqHandler(void);
|
||||
static void efc1IrqHandler(void);
|
||||
static void hsmc4IrqHandler(void);
|
||||
static void pioAIrqHandler(void);
|
||||
static void pioBIrqHandler(void);
|
||||
static void pioCIrqHandler(void);
|
||||
static void usart0IrqHandler(void);
|
||||
static void usart1IrqHandler(void);
|
||||
static void usart2IrqHandler(void);
|
||||
static void usart3IrqHandler(void);
|
||||
static void mci0IrqHandler(void);
|
||||
static void twi0IrqHandler(void);
|
||||
static void twi1IrqHandler(void);
|
||||
static void spi0IrqHandler(void);
|
||||
static void ssc0IrqHandler(void);
|
||||
static void tc0IrqHandler(void);
|
||||
static void tc1IrqHandler(void);
|
||||
static void tc2IrqHandler(void);
|
||||
static void pwmIrqHandler(void);
|
||||
static void adc0IrqHandler(void);
|
||||
static void adc1IrqHandler(void);
|
||||
static void hdmaIrqHandler(void);
|
||||
static void unusedIrqHandler(void);
|
||||
|
||||
__attribute__((section(".vectors"))) InterruptHandler interrupt_table[] = {
|
||||
// configure initial stack pointer using linker-generated symbols
|
||||
(InterruptHandler)&_estack,
|
||||
resetHandler,
|
||||
|
||||
nmiHandler,
|
||||
hardFaultHandler,
|
||||
memManagerHandler,
|
||||
busFaultHandler,
|
||||
usageFaultHandler,
|
||||
0, 0, 0, 0, // Reserved
|
||||
svcHandler,
|
||||
debugMonHandler,
|
||||
0, // Reserved
|
||||
pendSVHandler,
|
||||
sysTickHandler,
|
||||
|
||||
// Configurable interrupts
|
||||
supcIrqHandler, // 0 SUPPLY CONTROLLER
|
||||
rstcIrqHandler, // 1 RESET CONTROLLER
|
||||
rtcIrqHandler, // 2 REAL TIME CLOCK
|
||||
rttIrqHandler, // 3 REAL TIME TIMER
|
||||
wdtIrqHandler, // 4 WATCHDOG TIMER
|
||||
pmcIrqHandler, // 5 PMC
|
||||
efc0IrqHandler, // 6 EFC0
|
||||
efc1IrqHandler, // 7 EFC1
|
||||
dbgio_irqHandler, // 8 DBGU
|
||||
hsmc4IrqHandler, // 9 HSMC4
|
||||
pioAIrqHandler, // 10 Parallel IO Controller A
|
||||
pioBIrqHandler, // 11 Parallel IO Controller B
|
||||
pioCIrqHandler, // 12 Parallel IO Controller C
|
||||
usart0IrqHandler, // 13 USART 0
|
||||
usart1IrqHandler, // 14 USART 1
|
||||
usart2IrqHandler, // 15 USART 2
|
||||
usart3IrqHandler, // 16 USART 3
|
||||
mci0IrqHandler, // 17 Multimedia Card Interface
|
||||
twi0IrqHandler, // 18 TWI 0
|
||||
twi1IrqHandler, // 19 TWI 1
|
||||
spi0IrqHandler, // 20 Serial Peripheral Interface
|
||||
ssc0IrqHandler, // 21 Serial Synchronous Controller 0
|
||||
tc0IrqHandler, // 22 Timer Counter 0
|
||||
tc1IrqHandler, // 23 Timer Counter 1
|
||||
tc2IrqHandler, // 24 Timer Counter 2
|
||||
pwmIrqHandler, // 25 Pulse Width Modulation Controller
|
||||
adc0IrqHandler, // 26 ADC controller0
|
||||
adc1IrqHandler, // 27 ADC controller1
|
||||
hdmaIrqHandler, // 28 HDMA
|
||||
usbd_irqHandler, // 29 USB Device High Speed UDP_HS
|
||||
unusedIrqHandler // 30 not used
|
||||
};
|
||||
|
||||
// Memory Manage Address Register (MMAR) address valid flag
|
||||
#define CFSR_MMARVALID (0x01 << 7)
|
||||
// Bus Fault Address Register (BFAR) address valid flag
|
||||
#define CFSR_BFARVALID (0x01 << 15)
|
||||
|
||||
static void panic(const char* haltCause)
|
||||
{
|
||||
dprintf("%s -> Panic.\n\n", haltCause);
|
||||
while(1) {
|
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB19;
|
||||
for(int i = 0; i < 750000; i++) __NOP();
|
||||
AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB18;
|
||||
AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB19;
|
||||
for(int i = 0; i < 750000; i++) __NOP();
|
||||
}
|
||||
}
|
||||
|
||||
static void faultReport(const char *pFaultName, const u32* sp)
|
||||
{
|
||||
u32 cfsr;
|
||||
u32 mmfar;
|
||||
u32 bfar;
|
||||
|
||||
// Report fault
|
||||
dprintf("\n*** %s exception ***\n", pFaultName);
|
||||
cfsr = SCB->CFSR;
|
||||
mmfar = SCB->MMFAR;
|
||||
bfar = SCB->BFAR;
|
||||
|
||||
|
||||
dprintf("MPU->TYPE: 0x%08x MPU->CTRL: 0x%08x\n", MPU->TYPE, MPU->CTRL);
|
||||
|
||||
dprintf("HFSR: 0x%08x SHCSR: 0x%08x\n", SCB->HFSR, SCB->SHCSR);
|
||||
dprintf("ICSR: 0x%08x CFSR: 0x%08x\n", SCB->ICSR, SCB->CFSR);
|
||||
dprintf("MMSR: 0x%02x\n", (cfsr & 0xff));
|
||||
if((cfsr & CFSR_MMARVALID) != 0)
|
||||
dprintf("MMAR: 0x%08x\n", mmfar);
|
||||
dprintf("BFSR: 0x%02x\n", ((cfsr >> 8) & 0xff));
|
||||
if((cfsr & CFSR_BFARVALID) != 0)
|
||||
dprintf("BFAR: 0x%08x\n", bfar);
|
||||
dprintf("UFSR: 0x%04x HFSR: 0x%08x\n", ((cfsr >> 16) & 0xffff), (u32)SCB->HFSR);
|
||||
dprintf("DFSR: 0x%08x AFSR: 0x%08x\n", (u32)SCB->DFSR, (u32)SCB->AFSR);
|
||||
//dprintf(" LR: 0x%08x PC: 0x%08x\n", sp[5], sp[6]);
|
||||
dprintf("STACK:\n");
|
||||
for(int i = 0; i < 16; i++)
|
||||
dprintf("%02x: %08x\n", i, sp[i]);
|
||||
|
||||
// Clear fault status bits (write-clear)
|
||||
SCB->CFSR = SCB->CFSR;
|
||||
SCB->HFSR = SCB->HFSR;
|
||||
SCB->DFSR = SCB->DFSR;
|
||||
SCB->AFSR = SCB->AFSR;
|
||||
|
||||
panic("Exception");
|
||||
}
|
||||
|
||||
static void nmiHandler(void)
|
||||
{
|
||||
panic("NMI");
|
||||
}
|
||||
|
||||
void hardFaultHandlerBody(u32* sp)
|
||||
{
|
||||
faultReport("HardFault", sp);
|
||||
}
|
||||
|
||||
static void hardFaultHandler(void)
|
||||
{
|
||||
asm volatile ("tst lr, #0x4");
|
||||
asm volatile ("ite eq");
|
||||
asm volatile ("mrseq r0, msp");
|
||||
asm volatile ("mrsne r0, psp");
|
||||
asm volatile ("add r0, r0, #4");
|
||||
// because one word has been pushed to sp in this function
|
||||
asm volatile ("b hardFaultHandlerBody");
|
||||
}
|
||||
|
||||
void memManagerHandlerBody(u32* sp)
|
||||
{
|
||||
faultReport("MemManager", sp);
|
||||
}
|
||||
|
||||
static void memManagerHandler(void)
|
||||
{
|
||||
asm volatile ("tst lr, #0x4");
|
||||
asm volatile ("ite eq");
|
||||
asm volatile ("mrseq r0, msp");
|
||||
asm volatile ("mrsne r0, psp");
|
||||
asm volatile ("add r0, r0, #4");
|
||||
// because one word has been pushed to sp in this function
|
||||
asm volatile ("b memManagerHandlerBody");
|
||||
}
|
||||
|
||||
void busFaultHandlerBody(u32* sp)
|
||||
{
|
||||
faultReport("BusFault", sp);
|
||||
}
|
||||
|
||||
static void busFaultHandler(void)
|
||||
{
|
||||
asm volatile ("tst lr, #0x4");
|
||||
asm volatile ("ite eq");
|
||||
asm volatile ("mrseq r0, msp");
|
||||
asm volatile ("mrsne r0, psp");
|
||||
asm volatile ("add r0, r0, #4");
|
||||
// because one word has been pushed to sp in this function
|
||||
asm volatile ("b busFaultHandlerBody");
|
||||
}
|
||||
|
||||
void usageFaultHandlerBody(u32* sp)
|
||||
{
|
||||
faultReport("UsageFault", sp);
|
||||
}
|
||||
|
||||
static void usageFaultHandler(void)
|
||||
{
|
||||
asm volatile ("tst lr, #0x4");
|
||||
asm volatile ("ite eq");
|
||||
asm volatile ("mrseq r0, msp");
|
||||
asm volatile ("mrsne r0, psp");
|
||||
asm volatile ("add r0, r0, #4");
|
||||
// because one word has been pushed to sp in this function
|
||||
asm volatile ("b usageFaultHandlerBody");
|
||||
}
|
||||
|
||||
static void svcHandler(void)
|
||||
{
|
||||
panic("SVC");
|
||||
}
|
||||
|
||||
static void debugMonHandler(void)
|
||||
{
|
||||
panic("DebugMon");
|
||||
}
|
||||
|
||||
static void pendSVHandler(void)
|
||||
{
|
||||
panic("PendSV");
|
||||
}
|
||||
|
||||
static void sysTickHandler(void)
|
||||
{
|
||||
panic("SysTick");
|
||||
}
|
||||
|
||||
static void supcIrqHandler(void)
|
||||
{
|
||||
panic("SUPC");
|
||||
}
|
||||
|
||||
static void rstcIrqHandler(void)
|
||||
{
|
||||
panic("RSTC");
|
||||
}
|
||||
|
||||
static void rtcIrqHandler(void)
|
||||
{
|
||||
panic("RTC");
|
||||
}
|
||||
|
||||
static void rttIrqHandler(void)
|
||||
{
|
||||
panic("RTT");
|
||||
}
|
||||
|
||||
static void wdtIrqHandler(void)
|
||||
{
|
||||
panic("WDT");
|
||||
}
|
||||
|
||||
static void pmcIrqHandler(void)
|
||||
{
|
||||
panic("PMC");
|
||||
}
|
||||
|
||||
static void efc0IrqHandler(void)
|
||||
{
|
||||
panic("EFC0");
|
||||
}
|
||||
|
||||
static void efc1IrqHandler(void)
|
||||
{
|
||||
panic("EFC1");
|
||||
}
|
||||
|
||||
static void hsmc4IrqHandler(void)
|
||||
{
|
||||
panic("HSMC4");
|
||||
}
|
||||
|
||||
static void pioAIrqHandler(void)
|
||||
{
|
||||
panic("PIO-A");
|
||||
}
|
||||
|
||||
static void pioBIrqHandler(void)
|
||||
{
|
||||
panic("PIO-B");
|
||||
}
|
||||
|
||||
static void pioCIrqHandler(void)
|
||||
{
|
||||
panic("PIO-C");
|
||||
}
|
||||
|
||||
static void usart0IrqHandler(void)
|
||||
{
|
||||
panic("USART0");
|
||||
}
|
||||
|
||||
static void usart1IrqHandler(void)
|
||||
{
|
||||
panic("USART1");
|
||||
}
|
||||
|
||||
static void usart2IrqHandler(void)
|
||||
{
|
||||
panic("USART2");
|
||||
}
|
||||
|
||||
static void usart3IrqHandler(void)
|
||||
{
|
||||
panic("USART3");
|
||||
}
|
||||
|
||||
static void mci0IrqHandler(void)
|
||||
{
|
||||
panic("MCI0");
|
||||
}
|
||||
|
||||
static void twi0IrqHandler(void)
|
||||
{
|
||||
panic("TWI0");
|
||||
}
|
||||
|
||||
static void twi1IrqHandler(void)
|
||||
{
|
||||
panic("TWI1");
|
||||
}
|
||||
|
||||
static void spi0IrqHandler(void)
|
||||
{
|
||||
panic("SPI0");
|
||||
}
|
||||
|
||||
static void ssc0IrqHandler(void)
|
||||
{
|
||||
panic("SSC0");
|
||||
}
|
||||
|
||||
static void tc0IrqHandler(void)
|
||||
{
|
||||
panic("TC0");
|
||||
}
|
||||
|
||||
static void tc1IrqHandler(void)
|
||||
{
|
||||
panic("TC1");
|
||||
}
|
||||
|
||||
static void tc2IrqHandler(void)
|
||||
{
|
||||
panic("TC2");
|
||||
}
|
||||
|
||||
static void pwmIrqHandler(void)
|
||||
{
|
||||
panic("PWM");
|
||||
}
|
||||
|
||||
static void adc0IrqHandler(void)
|
||||
{
|
||||
panic("ADC0");
|
||||
}
|
||||
|
||||
static void adc1IrqHandler(void)
|
||||
{
|
||||
panic("ADC1");
|
||||
}
|
||||
|
||||
static void hdmaIrqHandler(void)
|
||||
{
|
||||
panic("HDMA");
|
||||
}
|
||||
|
||||
static void unusedIrqHandler(void)
|
||||
{
|
||||
panic("UNUSED");
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef INCLUDE_VECTORS_H
|
||||
#define INCLUDE_VECTORS_H
|
||||
|
||||
typedef void(*InterruptHandler)(void);
|
||||
extern InterruptHandler interrupt_table[];
|
||||
|
||||
void resetHandler(void); // implemented in startup.c
|
||||
void dbgio_irqHandler(void); // implemented in dbgio.c
|
||||
void usbd_irqHandler(void); // implemented in usbdhs.c
|
||||
|
||||
#endif // INCLUDE_VECTORS_H
|
|
@ -0,0 +1,77 @@
|
|||
Most of this code was originally written by Harald Welte, who used this
|
||||
license text:
|
||||
|
||||
/* (C) 2011-2012 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
Some files were taken from Atmel reference code, which contains the following
|
||||
copyright statement:
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
We also borrowed a bit from the Linux kernel - printf and folks:
|
||||
|
||||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
Also we use the ARM CMIS library:
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 15. February 2012
|
||||
* $Revision: V1.1.0
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* ----------------------------------------------------------------------*/
|
||||
|
||||
For all other files, the author is named in the header of the file.
|
|
@ -0,0 +1,171 @@
|
|||
# binary file name
|
||||
TARGET=radioapp
|
||||
|
||||
CROSS_COMPILE=arm-none-eabi-
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)gcc
|
||||
OBJCOPY=$(CROSS_COMPILE)objcopy
|
||||
OBJDUMP=$(CROSS_COMPILE)objdump
|
||||
BUILDDIR=build
|
||||
OBJDIR=$(BUILDDIR)/obj
|
||||
DEPDIR=$(BUILDDIR)/dep
|
||||
|
||||
RUMBA=rumba
|
||||
RUMBA_TTY=/dev/ttyACM0
|
||||
|
||||
# prevent make from displaying full command lines
|
||||
QUIET=@
|
||||
|
||||
C_SOURCES=\
|
||||
cmd_e4k.c \
|
||||
cmd_fpga.c \
|
||||
cmd_si570.c \
|
||||
cmd_sys.c \
|
||||
components.c \
|
||||
console.c \
|
||||
main.c \
|
||||
startup.c \
|
||||
vectors.c \
|
||||
\
|
||||
crt/ctype.c \
|
||||
crt/printf.c \
|
||||
crt/sprintf.c \
|
||||
crt/stdio.c \
|
||||
crt/string.c \
|
||||
crt/strtox.c \
|
||||
crt/vsprintf.c \
|
||||
crt/vprintf.c \
|
||||
\
|
||||
driver/chanfilter.c \
|
||||
driver/dbgio.c \
|
||||
driver/dma.c \
|
||||
driver/dmabuffer.c \
|
||||
driver/e4k.c \
|
||||
driver/flash.c \
|
||||
driver/led.c \
|
||||
driver/irq.c \
|
||||
driver/mci.c \
|
||||
driver/pio.c \
|
||||
driver/sdrfpga.c \
|
||||
driver/sdrmci.c \
|
||||
driver/sdrssc.c \
|
||||
driver/si570.c \
|
||||
driver/spi.c \
|
||||
driver/ssc.c \
|
||||
driver/sys.c \
|
||||
driver/twi.c \
|
||||
driver/usbdhs.c \
|
||||
\
|
||||
dsp/arm_bitreversal.c \
|
||||
dsp/arm_cfft_radix4_init_q31.c \
|
||||
dsp/arm_cfft_radix4_q31.c \
|
||||
dsp/arm_cmplx_mag_q31.c \
|
||||
dsp/arm_common_tables.c \
|
||||
dsp/arm_sqrt_q31.c \
|
||||
\
|
||||
usb/descriptors.c \
|
||||
usb/usb.c \
|
||||
usb/usbdevice.c
|
||||
|
||||
all: build
|
||||
|
||||
# general compiler flags
|
||||
CFLAGS=\
|
||||
-mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -fdata-sections -std=gnu99 \
|
||||
-O2 -g3 -Wall -Dat91sam3u4 -DARM_MATH_CM3 -D__CHECK_DEVICE_DEFINES \
|
||||
\
|
||||
-D__CM3_REV=0x0200 \
|
||||
-D__MPU_PRESENT=0 \
|
||||
-D__NVIC_PRIO_BITS=4 \
|
||||
-D__Vendor_SysTickConfig=0 \
|
||||
\
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fno-builtin-vsprintf \
|
||||
-fno-builtin-vprintf \
|
||||
-fno-builtin-puts \
|
||||
-fno-builtin-printf \
|
||||
-Wimplicit
|
||||
LDFLAGS=-g3 -Wl,-Map=$(BUILDDIR)/$(TARGET).map -nostdlib -nostartfiles -mcpu=cortex-m3 -mthumb -Wl,--gc-sections -T"src/at91sam3u4/flash.lds"
|
||||
LIBS=$(shell $(CC) -print-libgcc-file-name)
|
||||
|
||||
##############################################################################
|
||||
|
||||
SUBDIRS=$(sort $(dir $(C_SOURCES)))
|
||||
|
||||
DEPDIRS=$(addprefix $(DEPDIR)/,$(SUBDIRS))
|
||||
OBJDIRS=$(addprefix $(OBJDIR)/,$(SUBDIRS))
|
||||
|
||||
COBJS=$(addprefix $(OBJDIR)/,$(C_SOURCES:%.c=%.o))
|
||||
DEPS=$(C_SOURCES:%.c=%.dep)
|
||||
FULLDEPS=$(addprefix $(DEPDIR)/,$(DEPS))
|
||||
|
||||
BUILD_DATE=$(shell date "+%Y-%m-%d")
|
||||
BUILD_TIME=$(shell date "+%H:%M:%S")
|
||||
BUILD_ZONE=$(shell date "+%Z")
|
||||
BUILD_HOST=$(shell uname -n)
|
||||
BUILD_GCC=$(shell $(CC) --version | head -1)
|
||||
BUILD_VCSID=$(shell ../../git-version-gen ../../.tarball_version)
|
||||
|
||||
.PHONY: all build buildid clean distclean dfuflash
|
||||
|
||||
build: $(OBJDIRS) $(DEPDIRS) buildid $(BUILDDIR)/$(TARGET).bin $(BUILDDIR)/$(TARGET).asm
|
||||
|
||||
buildid: $(OBJDIRS)
|
||||
@echo [GEN]\ $(BUILDDIR)/buildid.h
|
||||
$(QUIET)echo -en \
|
||||
"#ifndef INCLUDE_BUILDID_H\n"\
|
||||
"#define INCLUDE_BUILDID_H\n"\
|
||||
"\n"\
|
||||
"#define BUILDID_DATE \"$(BUILD_DATE)\"\n"\
|
||||
"#define BUILDID_TIME \"$(BUILD_TIME)\"\n"\
|
||||
"#define BUILDID_ZONE \"$(BUILD_ZONE)\"\n"\
|
||||
"#define BUILDID_HOST \"$(BUILD_HOST)\"\n"\
|
||||
"#define BUILDID_GCC \"$(BUILD_GCC)\"\n"\
|
||||
"#define BUILDID_VCSID \"$(BUILD_VCSID)\"\n"\
|
||||
"\n"\
|
||||
"#endif // INCLUDE_BUILDID_H\n"\
|
||||
> $(BUILDDIR)/buildid.h
|
||||
|
||||
-include $(FULLDEPS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET).bin: $(BUILDDIR)/$(TARGET).elf
|
||||
@echo [BIN] $@
|
||||
$(QUIET)$(OBJCOPY) \
|
||||
-O binary $(BUILDDIR)/$(TARGET).elf $(BUILDDIR)/$(TARGET).bin
|
||||
$(QUIET)ls -la $@ | awk '{ print " image has", $$5, "bytes"; }'
|
||||
|
||||
$(BUILDDIR)/$(TARGET).asm: $(BUILDDIR)/$(TARGET).elf
|
||||
@echo [ASM] $@
|
||||
$(QUIET)$(OBJDUMP) \
|
||||
-deS --disassembler-options=force-thumb $(BUILDDIR)/$(TARGET).elf > $(BUILDDIR)/$(TARGET).asm
|
||||
|
||||
$(BUILDDIR)/$(TARGET).elf: $(COBJS)
|
||||
@echo [LD\ ]\ $@
|
||||
$(QUIET)$(LD) \
|
||||
$(LDFLAGS) \
|
||||
-o $(BUILDDIR)/$(TARGET).elf \
|
||||
-Wl,--start-group $(COBJS) $(LIBS) -Wl,--end-group
|
||||
|
||||
$(COBJS):
|
||||
@echo [C\ \ ]\ $(patsubst %.o,%.c,$(patsubst $(OBJDIR)/%,%,$@))
|
||||
$(QUIET)$(CC) \
|
||||
$(CFLAGS) \
|
||||
$(CFLAGS_$(subst /,_,$(patsubst %.o,%,$(patsubst $(OBJDIR)/%,%,$@)))) \
|
||||
-MD -MP -MF $(patsubst %.o,$(DEPDIR)/%.dep,$(patsubst $(OBJDIR)/%,%,$@)) \
|
||||
-c src/$(patsubst %.o,%.c,$(patsubst $(OBJDIR)/%,%,$@)) \
|
||||
-o $@
|
||||
|
||||
$(OBJDIRS) $(DEPDIRS) $(GENERATED):
|
||||
$(QUIET)mkdir -p $@
|
||||
|
||||
clean:
|
||||
@echo [CLEAN]
|
||||
$(QUIET)rm -Rf $(OBJDIR) $(DEPDIR) $(BUILDDIR)/buildid.h
|
||||
|
||||
distclean:
|
||||
@echo [DISTCLEAN]
|
||||
$(QUIET)rm -Rf $(BUILDDIR)
|
||||
|
||||
dfuflash: build
|
||||
$(QUIET)sudo dfu-util -d 16c0:0763 -a 0 -D $(BUILDDIR)/$(TARGET).bin -R
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,140 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \unit
|
||||
/// !Purpose
|
||||
///
|
||||
/// Definition of AT91SAM3U4 characteristics and features
|
||||
///
|
||||
/// !Usage
|
||||
/// -# For ARM core feature, see "AT91SAM3U4 - ARM core features".
|
||||
/// -# For IP features, see "AT91SAM3U4 - IP features".
|
||||
/// -# For misc, see "AT91SAM3U4 - Misc".
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef CHIP_H
|
||||
#define CHIP_H
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Headers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Definitions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - ARM core features"
|
||||
/// This page lists several characteristics related to the ARM core
|
||||
///
|
||||
|
||||
//ARM core features
|
||||
|
||||
/// ARM core definition.
|
||||
#define cortexm3
|
||||
|
||||
/// family definition.
|
||||
#define at91sam3u
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - IP features"
|
||||
/// This page lists several characteristics related to the embedded IP
|
||||
///
|
||||
|
||||
//IP FEATURES
|
||||
|
||||
// EFC GPNVM number
|
||||
#define CHIP_EFC_NUM_GPNVMS 3
|
||||
|
||||
/// Indicates chip has an Enhanced EFC.
|
||||
#define CHIP_FLASH_EEFC
|
||||
|
||||
// DMA channels number
|
||||
#define CHIP_DMA_CHANNEL_NUM 4
|
||||
|
||||
// Indicate chip's MCI interface.
|
||||
#define MCI2_INTERFACE
|
||||
|
||||
// Indicate chip has a nandflash controller.
|
||||
#define CHIP_NAND_CTRL
|
||||
|
||||
// Indicate chip SSC has DMA interface.
|
||||
#define CHIP_SSC_DMA
|
||||
|
||||
// Indicate chip SPI has DMA interface.
|
||||
#define CHIP_SPI_DMA
|
||||
|
||||
/// Indicates chip has an UDP High Speed.
|
||||
#define CHIP_USB_UDPHS
|
||||
|
||||
/// Indicates chip has an internal pull-up.
|
||||
#define CHIP_USB_PULLUP_INTERNAL
|
||||
|
||||
/// Number of USB endpoints
|
||||
#define CHIP_USB_NUMENDPOINTS 7
|
||||
|
||||
/// Endpoints max paxcket size
|
||||
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
|
||||
((i == 0) ? 64 : \
|
||||
((i == 1) ? 512 : \
|
||||
((i == 2) ? 512 : \
|
||||
((i == 3) ? 64 : \
|
||||
((i == 4) ? 64 : \
|
||||
((i == 5) ? 1024 : \
|
||||
((i == 6) ? 1024 : 0 )))))))
|
||||
|
||||
/// Endpoints Number of Bank
|
||||
#define CHIP_USB_ENDPOINTS_BANKS(i) \
|
||||
((i == 0) ? 1 : \
|
||||
((i == 1) ? 2 : \
|
||||
((i == 2) ? 2 : \
|
||||
((i == 3) ? 3 : \
|
||||
((i == 4) ? 3 : \
|
||||
((i == 5) ? 3 : \
|
||||
((i == 6) ? 3 : 0 )))))))
|
||||
|
||||
/// Endpoints max paxcket size
|
||||
#define CHIP_USB_ENDPOINTS_DMA(i) \
|
||||
((i == 1) ? 1 : \
|
||||
((i == 2) ? 1 : \
|
||||
((i == 3) ? 1 : \
|
||||
((i == 4) ? 1 : \
|
||||
((i == 5) ? 1 : \
|
||||
((i == 6) ? 1 : 0 ))))))
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// \page "AT91SAM3U4 - Misc "
|
||||
/// This page lists misc features
|
||||
///
|
||||
|
||||
//Misc
|
||||
|
||||
#endif //#ifndef CHIP_H
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue