Compare commits

...
This repository has been archived on 2022-02-18. You can view files and clone it, but cannot push or open issues or pull requests.

37 Commits

Author SHA1 Message Date
Dimitri Stolnikov 562b31a64e cross platform usleep() 2015-12-11 18:41:44 +01:00
Dimitri Stolnikov b697821a8d cmake: add version module 2013-06-04 20:32:31 +02:00
Hoernchen 0e00ac4663 resolve define clash w/ gr-osmosdr 2013-04-14 13:12:08 +02:00
Christian Daniel 159bd582a4 improve fault reporting for radio application 2013-02-14 16:27:46 +01:00
Christian Daniel 43e6448d0c add early debugging via UART during boot process 2013-02-14 16:27:32 +01:00
Christian Daniel d0360315b3 improve panic dump 2013-02-13 19:58:27 +01:00
Christian Daniel 4ec94b60bd add 'default' S/N 2013-02-13 19:58:12 +01:00
Christian Daniel fc74cd8ce9 make sure, interrupts are _really_ disabled 2013-02-13 19:58:03 +01:00
Christian Daniel 0e7bfc6097 fix flash read access during flash_readUID (__get_FAULTMASK was not inlined) 2013-02-13 19:57:36 +01:00
Christian Daniel 41184d6706 set MPU_PRESENT macro 2013-02-13 19:56:46 +01:00
Christian Daniel 6b77966f35 Merge commit '4349afe1f6f4cb4941bf8ba58d72dd8fb45a2745' into mci-rewrite 2013-02-07 19:44:21 +01:00
Christian Daniel 559a3b1e90 Make: switch to speed optimized code 2013-02-07 19:41:30 +01:00
Christian Daniel ba4ebda883 FPGA: switch off PWM signals to E4K *grrrrrrr* 2013-02-07 19:41:15 +01:00
Christian Daniel a2883095ed FPGA-Console: add FPGA test mode command 2013-02-07 19:40:59 +01:00
Christian Daniel 3088cd904e DMABuffers: add id to buffers 2013-02-07 19:40:43 +01:00
Christian Daniel 8c60ae3746 MCI: switch MCI block size to 64 to remove blockyness from EMI 2013-02-07 19:40:25 +01:00
Christian Daniel 08ac2f7e4c DMA: half the size of the buffers, double the number 2013-02-07 19:39:50 +01:00
Christian Daniel b4c4d46fb1 USBDevice: modify command to configure E4K dc offset 2013-02-07 19:38:18 +01:00
Christian Daniel 5ee4d33c02 libosmosdr: add call to configure E4K DC offset 2013-02-07 19:36:29 +01:00
Christian Daniel c0383b32a3 Merge branch 'master' of git.osmocom.org:osmo-sdr into mci-rewrite 2013-02-07 17:36:15 +01:00
Hoernchen 4349afe1f6 add current VHDL source 2013-01-22 18:21:31 +01:00
Christian Vogel ffec059aeb Replace obsolete automake AM_CONFIG_HEADER.
This fixes the following complaint by autoconf 2.69-1, automake 1.13.1-1.

: configure.ac:80: error: 'AM_CONFIG_HEADER': this macro is obsolete.
: You should use the 'AC_CONFIG_HEADERS' macro instead.
: /usr/share/aclocal-1.13/obsolete-err.m4:12: AM_CONFIG_HEADER is expan
: configure.ac:80: the top level

Automake 1:1.11.3-1ubuntu2, autoconf 2.68-1ubuntu2 don't even emit a warning
without, and work just fine with this patch.

Signed-off-by: Christian Vogel <vogelchr@vogel.cx>
Signed-off-by: Steve Markgraf <steve@steve-m.de>
2013-01-13 22:37:26 +01:00
Christian Daniel a5a3280178 do more resets on twi hardware to resolve lockups 2013-01-10 19:11:53 +01:00
Christian Daniel 4952c3f05e switch off MCI pullups 2013-01-10 19:11:34 +01:00
Christian Daniel f632a7b7b8 optimize fpga initialisation 2013-01-10 19:11:24 +01:00
Christian Daniel b4e144f150 add direct register writing via console to e4k and fpga 2013-01-10 19:11:06 +01:00
Christian Daniel bc917000f5 - make MCI switch transfer frequency according to needed bandwidth
- add "switch to DFU" command to USB
- cleanup usb device code (comments and error handling)
- add E4K register write via USB
2013-01-10 19:10:41 +01:00
Christian Daniel cc2fc0e5b6 use internal LED for loader status info 2013-01-10 18:06:22 +01:00
Christian Daniel 8d91910f74 Merge branch 'master' of git.osmocom.org:osmo-sdr into mci-rewrite 2013-01-10 15:43:26 +01:00
Christian Daniel ed0d85cf33 add version information to firmware binaries 2012-10-21 20:39:29 +02:00
Christian Daniel e26ecd5227 DFU: properly initialize RAM 2012-10-21 20:10:40 +02:00
Christian Daniel 48311dbf93 libosmosdr: add control function for i/q op amps 2012-10-21 19:51:17 +02:00
Christian Daniel d5a6df3a4d add schematics for OpAmp/SDIO stack-on-board 2012-10-18 22:32:58 +02:00
Christian Daniel a697e6afe2 add SDIO based FPGA bitstreams - source code to follow later 2012-10-18 22:32:40 +02:00
Christian Daniel f077a9c4cb import new, rewritten, MCI/SDIO interfacing firmware 2012-10-18 22:32:15 +02:00
Christian Daniel 7cbe4b852e move 'classic' firmware to firmware-old 2012-10-18 22:31:35 +02:00
Christian Daniel b17fd2ca39 make rum-ba reset the device after flashing 2012-10-18 22:22:54 +02:00
254 changed files with 61194 additions and 33 deletions

View File

@ -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.

View 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

View File

@ -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

View File

@ -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

View File

@ -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 = .;

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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++);
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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) ;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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) ;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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.

View 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

View File

@ -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