[sky9x] Massstorage (not finished at all!)

[stock] 180bytes flash saved
This commit is contained in:
bsongis
2012-09-11 19:58:49 +00:00
parent 91fbcb94d7
commit fcf6f436b0
702 changed files with 166014 additions and 441 deletions
+2 -1
View File
@@ -424,6 +424,7 @@ ifeq ($(PCB), ARM)
# V4 ARM, so ...
OPT = 2
CPPDEFS += -DPCBARM -DAUDIO -DHAPTIC -DPXX -DDSM2 -DDSM2_PPM -DROTARY_ENCODERS=1
# CPPDEFS += -DMASSSTORAGE -DDEBUG # Both must come together today!
EXTRAINCDIRS += ersky9x ersky9x/libraries ersky9x/libraries/drivers CoOS/kernel CoOS/portable
BOARDSRC = board_ersky9x.cpp
SRC += ersky9x/core_cm3.c ersky9x/board_lowlevel.c ersky9x/crt.c ersky9x/vectors_sam3s.c
@@ -432,7 +433,7 @@ ifeq ($(PCB), ARM)
SRC += ersky9x/libraries/usb/common/core/USBInterfaceRequest.c ersky9x/libraries/usb/common/core/USBGetDescriptorRequest.c ersky9x/libraries/usb/common/core/USBSetAddressRequest.c ersky9x/libraries/usb/common/core/USBSetConfigurationRequest.c ersky9x/libraries/usb/common/core/USBConfigurationDescriptor.c ersky9x/libraries/usb/common/core/USBGenericDescriptor.c
SRC += ersky9x/libraries/usb/device/core/USBDCallbacks_Resumed.c ersky9x/libraries/usb/device/core/USBDCallbacks_Reset.c ersky9x/libraries/usb/device/core/USBDCallbacks_Suspended.c ersky9x/libraries/usb/device/core/USBDCallbacks_Initialized.c ersky9x/libraries/usb/device/core/USBDDriverCb_IfSettingChanged.c # TODO remove them
SRC += ersky9x/libraries/usb/device/massstorage/MSDLun.c ersky9x/libraries/usb/device/massstorage/MSDDriverDescriptors.c
SRC += ../Atmel/sam3s/sam3s-ek/libraries/libboard_sam3s-ek/source/syscalls.c # TODO move it
SRC += ersky9x/syscalls.c
SRC += ersky9x/libraries/usb/device/massstorage/SBCMethods.c
EEPROMSRC = eeprom_arm.cpp
PULSESSRC = pulses_arm.cpp
+1
View File
@@ -896,6 +896,7 @@ void eeReadAll()
theFile.writeRlc(FILE_GENERAL, FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral), true);
modelDefault(0);
theFile.writeRlc(FILE_MODEL(0), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model), true);
}
+16 -1
View File
@@ -41,7 +41,7 @@
* This function is synchronous (i.e. uses polling).
* c Character to send.
*/
void debugPutc(const uint8_t c)
void debugPutc(const char c)
{
Uart *pUart = CONSOLE_USART;
@@ -68,6 +68,21 @@ void debugPuts(const char *format, ...)
}
}
void dump(unsigned char *data, unsigned int size)
{
debugPuts("DUMP %d bytes ...\n\r", size);
unsigned int i = 0, j=0;
while (i*32+j < size) {
debugPuts("%.2X ", data[i*32+j]);
j++;
if (j==32) {
i++; j=0;
debugPuts("\n\r");
}
}
debugPuts("\n\r");
}
Fifo32 debugFifo;
extern "C" void UART0_IRQHandler()
+32 -4
View File
@@ -35,13 +35,41 @@
#define debug_h
#if defined(DEBUG)
void debugPutc(const uint8_t c);
#ifdef __cplusplus
extern "C" {
#endif
void debugPutc(const char c);
void debugPuts(const char *string, ...);
void dump(unsigned char *data, unsigned int size);
#ifdef __cplusplus
}
#endif
#define TRACE_DEBUG(...) debugPuts("-D- " __VA_ARGS__)
#define TRACE_DEBUG_WP(...) debugPuts(__VA_ARGS__)
#define TRACE_INFO(...) debugPuts("-I- " __VA_ARGS__)
#define TRACE_INFO_WP(...) debugPuts(__VA_ARGS__)
#define TRACE_WARNING(...) debugPuts("-W- " __VA_ARGS__)
#define TRACE_WARNING_WP(...) debugPuts(__VA_ARGS__)
#define TRACE_ERROR(...) debugPuts("-E- " __VA_ARGS__)
#define DUMP(data, size) dump(data, size)
void debugTask(void* pdata);
#else
#define debugPutc(...)
#define debugPuts(...)
#define debugTask(...)
#define TRACE_DEBUG(...) { }
#define TRACE_DEBUG_WP(...) { }
#define TRACE_INFO(...) { }
#define TRACE_INFO_WP(...) { }
#define TRACE_WARNING(...) { }
#define TRACE_WARNING_WP(...) { }
#define TRACE_ERROR(...) { }
#define DUMP(...) { }
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,130 @@
/* ----------------------------------------------------------------------------
* 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 AT91SAM3S4 characteristics and features
///
/// !Usage
/// -# For ARM core feature, see "AT91SAM3S4 - ARM core features".
/// -# For IP features, see "AT91SAM3S4 - IP features".
/// -# For misc, see "AT91SAM3S4 - Misc".
//------------------------------------------------------------------------------
#ifndef CHIP_H
#define CHIP_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \page "AT91SAM3S4 - ARM core features"
/// This page lists several characteristics related to the ARM core
///
//ARM core features
/// ARM core definition.
#define cortexm3
/// family definition.
#define at91sam3s
//------------------------------------------------------------------------------
/// \page "AT91SAM3S4 - 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 SSC has DMA interface.
#define CHIP_SSC_DMA
// Indicate chip SPI has DMA interface.
#define CHIP_SPI_DMA
/// Indicates chip has an UDP Full Speed.
#define CHIP_USB_UDP
/// Indicates chip has an internal pull-up.
#define CHIP_USB_PULLUP_INTERNAL
/// Number of USB endpoints
#define CHIP_USB_NUMENDPOINTS 8
/// Endpoints max paxcket size
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
((i == 0) ? 64 : \
((i == 1) ? 64 : \
((i == 2) ? 64 : \
((i == 3) ? 64 : \
((i == 4) ? 512 : \
((i == 5) ? 512 : \
((i == 6) ? 64 : \
((i == 7) ? 64 : 0 ))))))))
/// Endpoints Number of Bank
#define CHIP_USB_ENDPOINTS_BANKS(i) \
((i == 0) ? 1 : \
((i == 1) ? 2 : \
((i == 2) ? 2 : \
((i == 3) ? 1 : \
((i == 4) ? 2 : \
((i == 5) ? 2 : \
((i == 6) ? 2 : \
((i == 7) ? 2 : 0 ))))))))
//------------------------------------------------------------------------------
/// \page "AT91SAM3S4 - Misc "
/// This page lists misc features
///
//Misc
#endif //#ifndef CHIP_H
@@ -0,0 +1,30 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Vector table start*/
define symbol __ICFEDIT_vector_start__ = 0x000400000; /*Add for CMSIS*/
/*-Memory Regions-*/
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
define symbol __ICFEDIT_region_ROM_start__ = 0x00400000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0043FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x200;
export symbol __ICFEDIT_vector_start__; /*Add for CMSIS*/
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_vector_start__ { readonly section .vectors }; /*Add for CMSIS*/
place in ROM_region { readonly };
place in RAM_region { readwrite,,block CSTACK, block HEAP };
@@ -0,0 +1,81 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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 AT91SAM3S4
*----------------------------------------------------------------------------*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(ResetException)
/* Memory Spaces Definitions */
MEMORY
{
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0000C000 /* sram, 48K */
flash (W!RX) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* Flash, 256K */
}
SECTIONS
{
.fixed :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors))
*(.text*)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_efixed = .; /* End of text section */
} >flash
.relocate : AT (_efixed)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc);
*(.data);
. = ALIGN(4);
_erelocate = .;
} >sram
.bss (NOLOAD) : {
. = ALIGN(4);
_szero = .;
*(.bss)
. = ALIGN(4);
_ezero = .;
} >sram
/* Stack in the end of SRAM */
_estack = 0x2000BFFC;
}
end = .;
@@ -0,0 +1,27 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Vector table start*/
define symbol __ICFEDIT_vector_start__ = 0x20000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000BFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x900;
define symbol __ICFEDIT_size_heap__ = 0x200;
/*-Exports-*/
export symbol __ICFEDIT_vector_start__;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
/* define block RamVect with alignment = 8, size = __ICFEDIT_size_vectors__ { }; */
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_vector_start__ { readonly section .vectors };
place in RAM_region { readonly, readwrite, block CSTACK, block HEAP };
@@ -0,0 +1,81 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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 SRAM on the AT91SAM3S4
*----------------------------------------------------------------------------*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(ResetException)
/* Memory Spaces Definitions */
MEMORY
{
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0000C000 /* sram, 48K */
}
SECTIONS
{
.fixed :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors))
*(.text*)
*(.ramfunc)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_efixed = .; /* End of text section */
} > sram
.relocate : AT (_efixed)
{
. = ALIGN(4);
_srelocate = .;
*(.data)
. = ALIGN(4);
_erelocate = .;
} >sram
.bss (NOLOAD) : {
. = ALIGN(4);
_szero = .;
*(.bss)
. = ALIGN(4);
_ezero = .;
} >sram
/* Stack in the end of SRAM */
_estack = 0x2000BFFC;
}
end = .;
+673
View File
@@ -0,0 +1,673 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
/**
* \page sam3s_ek_board_desc "SAM3S-EK - Board Description"
*
* \section
* A file is dedicated to descibe the AT91SAM3S-EK board.
*
* \section Contents
* - The code for booting the board is provided by board_cstartup.S and
* board_lowlevel.c.
* - For using board PIOs, board characteristics (clock, etc.) and external
* components, see board.h.
* - For manipulating memories (remapping, SDRAM, etc.), see board_memories.h.
*
* To get more software details and the full list of parameters related to the
* SAM3S-EK board configuration, please have a look at the source file: \n
* \ref board.h\n
*
* This file can be used as a template and modified to fit a custom board, with
* specific PIOs usage or memory connections.
**/
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \file board.h
///
/// \par Purpose
///
/// Definition of AT91SAM3S-EK characteristics, AT91SAM3S-dependant PIOs and
/// external components interfacing.
///
/// \par Usage
/// -# For operating frequency information, see "SAM3S-EK - Operating frequencies".
/// -# For using portable PIO definitions, see "SAM3S-EK - PIO definitions".
/// -# Several USB definitions are included here (see "SAM3S-EK - USB device").
//------------------------------------------------------------------------------
#ifndef BOARD_H
#define BOARD_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
/* These headers were introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */
#include <stdint.h>
#include <stdbool.h>
#if defined(at91sam3s4)
#include "at91sam3s4/chip.h"
#include "at91sam3s4/AT91SAM3S4.h"
#else
#error Board does not support the specified chip.
#endif
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par
/// This page lists several definition related to the board description.
///
/// Definitions
/// - BOARD_NAME
/// Name of the board.
#define BOARD_NAME "AT91SAM3S-EK"
/// Board definition.
#define at91sam3sek
/// Family definition (already defined).
#define at91sam3s
/// Core definition
#define cortexm3
//#define BOARD_REV_A
#define BOARD_REV_B
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par sam3s_ek_opfreq "SAM3S-EK - Operating frequencies"
/// This page lists several definition related to the board operating frequency
/// (when using the initialization done by board_lowlevel.c).
///
/// !Definitions
/// - BOARD_MAINOSC
/// - BOARD_MCK
/// Frequency of the board main oscillator.
#define BOARD_MAINOSC 12000000
/// Master clock frequency (when using board_lowlevel.c).
//#define BOARD_MCK 48000000
#define BOARD_MCK 64000000
//------------------------------------------------------------------------------
// ADC
//------------------------------------------------------------------------------
/// Startup time max, return from Idle mode (in µs)
#define ADC_STARTUP_TIME_MAX 15
/// Track and hold Acquisition Time min (in ns)
#define ADC_TRACK_HOLD_TIME_MIN 1200
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// USB attributes configuration descriptor (bus or self powered, remote wakeup)
//#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par sam3s_ek_piodef "SAM3S-EK - PIO definitions"
/// This pages lists all the pio definitions contained in board.h. The constants
/// are named using the following convention: PIN_* for a constant which defines
/// a single Pin instance (but may include several PIOs sharing the same
/// controller), and PINS_* for a list of Pin instances.
///
/// !ADC
/// - PIN_ADC0_AD0
/// - PIN_ADC0_AD1
/// - PIN_ADC0_AD2
/// - PIN_ADC0_AD3
/// - PIN_ADC0_AD4
/// - PIN_ADC0_AD5
/// - PIN_ADC0_AD6
/// - PIN_ADC0_AD7
/// - PINS_ADC0
///
/// !UART
/// - PINS_UART
///
/// !EBI
/// - PIN_EBI_DATA_BUS
/// - PIN_EBI_NCS0
/// - PIN_EBI_NRD
/// - PIN_EBI_NWE
/// - PIN_EBI_ADDR_BUS
/// - PIN_EBI_PSRAM_NBS
/// - PIN_EBI_A1
/// - PIN_EBI_LCD_RS
///
/// !LEDs
/// - PIN_LED_0
/// - PIN_LED_1
/// - PIN_LED_2
/// - PINS_LEDS
///
/// !MCI
/// - PINS_MCI
///
/// !Push buttons
/// - PIN_PUSHBUTTON_1
/// - PIN_PUSHBUTTON_2
/// - PINS_PUSHBUTTONS
/// - PUSHBUTTON_BP1
/// - PUSHBUTTON_BP2
///
/// !PWMC
/// - PIN_PWMC_PWMH0
/// - PIN_PWMC_PWML0
/// - PIN_PWMC_PWMH1
/// - PIN_PWMC_PWML1
/// - PIN_PWMC_PWMH2
/// - PIN_PWMC_PWML2
/// - PIN_PWMC_PWMH3
/// - PIN_PWMC_PWML3
/// - PIN_PWM_LED0
/// - PIN_PWM_LED1
/// - PIN_PWM_LED2
/// - CHANNEL_PWM_LED0
/// - CHANNEL_PWM_LED1
/// - CHANNEL_PWM_LED2
///
/// !SPI
/// - PIN_SPI_MISO
/// - PIN_SPI_MOSI
/// - PIN_SPI_SPCK
/// - PINS_SPI
/// - PIN_SPI_NPCS0_PA11
///
/// ! SSC
/// - PIN_SSC_TD
/// - PIN_SSC_TK
/// - PIN_SSC_TF
/// - PINS_SSC_CODEC
///
/// ! PCK0
/// - PIN_PCK0
///
/// !TWI
/// - PIN_TWI_TWD0
/// - PIN_TWI_TWCK0
/// - PINS_TWI
///
/// !USART0
/// - PIN_USART0_RXD
/// - PIN_USART0_TXD
/// - PIN_USART0_CTS
/// - PIN_USART0_RTS
/// - PIN_USART0_SCK
///
/// !USB
/// - PIN_USB_PULLUP
///
/// ADC_AD0 pin definition.
#define PIN_ADC0_AD0 {1 << 21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD1 pin definition.
#define PIN_ADC0_AD1 {1 << 30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD2 pin definition.
#define PIN_ADC0_AD2 {1 << 3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD3 pin definition.
#define PIN_ADC0_AD3 {1 << 4, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD4 pin definition.
#define PIN_ADC0_AD4 {1 << 15, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD5 pin definition.
#define PIN_ADC0_AD5 {1 << 16, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD6 pin definition.
#define PIN_ADC0_AD6 {1 << 17, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
/// ADC_AD7 pin definition.
#define PIN_ADC0_AD7 {1 << 18, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
/// Pins ADC
#define PINS_ADC PIN_ADC0_AD0, PIN_ADC0_AD1, PIN_ADC0_AD2, PIN_ADC0_AD3, PIN_ADC0_AD4, PIN_ADC0_AD5, PIN_ADC0_AD6, PIN_ADC0_AD7
/** UART pins (UTXD0 and URXD0) definitions, PA9,10. */
#define PINS_UART {0x00000600, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/// EBI
#define PIN_EBI_DATA_BUS {0xFF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NRD {1 << 11, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NWE {1 << 8, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NCS0 {1 << 20, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_PSRAM_ADDR_BUS {0x3f00fff, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_PSRAM_NBS {1 << 7, PIOB, ID_PIOB, PIO_PERIPH_B, PIO_PULLUP}, \
{1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_A1 {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NCS1 {1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD CS pin */
#define PIN_EBI_LCD_RS {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD RS pin */
#ifdef BOARD_REV_A
/** LED #0 pin definition. */
#define PIN_LED_0 {1 << 20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
/** LED #1 pin definition. */
#define PIN_LED_1 {1 << 21, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
/** LED #2 pin definition. */
#define PIN_LED_2 {1 << 22, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
#endif
#ifdef BOARD_REV_B
/** LED #0 pin definition. */
#define PIN_LED_0 {1 << 19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/** LED #1 pin definition. */
#define PIN_LED_1 {1 << 20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/** LED #2 pin definition. */
#define PIN_LED_2 {1 << 20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
#endif
/** List of all LEDs definitions. */
#define PINS_LEDS PIN_LED_0, PIN_LED_1, PIN_LED_2
#if 0
// TODO check BSS
/// MCI pins definition.
#define PINS_MCI {0x1f8, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_PULLUP}, \
{1 << 3, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/// MCI pin Card Detect
#define PIN_MCI_CD \
{AT91C_PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
#endif
/** Push button #0 definition. Attributes = pull-up + debounce + interrupt on rising edge. */
#define PIN_PUSHBUTTON_1 {1 << 3, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE}
/** Push button #1 definition. Attributes = pull-up + debounce + interrupt on falling edge. */
#define PIN_PUSHBUTTON_2 {1 << 12, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE}
/** List of all push button definitions. */
#define PINS_PUSHBUTTONS PIN_PUSHBUTTON_1, PIN_PUSHBUTTON_2
/** Push button #1 index. */
#define PUSHBUTTON_BP1 0
/** Push button #2 index. */
#define PUSHBUTTON_BP2 1
/// Simulated joystick LEFT index.
#define JOYSTICK_LEFT 0
/// Simulated joystick RIGHT index.
#define JOYSTICK_RIGHT 1
/** PWMC PWM0 pin definition. */
#define PIN_PWMC_PWMH0 {1 << 18, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
#define PIN_PWMC_PWML0 {1 << 19, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/** PWMC PWM1 pin definition. */
#define PIN_PWMC_PWMH1 {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
#define PIN_PWMC_PWML1 {1 << 20, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/** PWMC PWM2 pin definition. */
#define PIN_PWMC_PWMH2 {1 << 20, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
#define PIN_PWMC_PWML2 {1 << 16, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
/** PWMC PWM3 pin definition. */
#define PIN_PWMC_PWMH3 {1 << 21, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
#define PIN_PWMC_PWML3 {1 << 15, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
/** PWM pin definition for LED0 */
#define PIN_PWM_LED0 PIN_PWMC_PWMH0, PIN_PWMC_PWML0
/** PWM pin definition for LED1 */
#define PIN_PWM_LED1 PIN_PWMC_PWMH2, PIN_PWMC_PWML2
/** PWM pin definition for LED2 */
#define PIN_PWM_LED2 PIN_PWMC_PWMH3, PIN_PWMC_PWML3
/** PWM channel for LED0 */
#define CHANNEL_PWM_LED0 0
/** PWM channel for LED1 */
#define CHANNEL_PWM_LED1 2
/** PWM channel for LED2 */
#define CHANNEL_PWM_LED2 3
/** SPI MISO pin definition. */
#define PIN_SPI_MISO {1 << 12, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI MOSI pin definition. */
#define PIN_SPI_MOSI {1 << 13, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI SPCK pin definition. */
#define PIN_SPI_SPCK {1 << 14, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** SPI chip select pin definition. */
#define PIN_SPI_NPCS0_PA11 {1 << 11, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/** List of SPI pin definitions (MISO, MOSI & SPCK). */
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
/// SSC pins definition.
#define PIN_SSC_TD {0x1 << 26, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SSC_TK {0x1 << 28, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SSC_TF {0x1 << 30, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PINS_SSC_CODEC PIN_SSC_TD, PIN_SSC_TK, PIN_SSC_TF
/// PCK0
#define PIN_PCK0 {0x1 << 21, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
/// TWI pins definition.
#define TWI_V3XX
#define PIN_TWI_TWD0 {0x1 << 9, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_TWI_TWCK0 {0x1 << 10, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PINS_TWI0 PIN_TWI_TWD0, PIN_TWI_TWCK0
#define PIN_TWI_TWD1 {0x1 << 24, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_TWI_TWCK1 {0x1 << 25, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PINS_TWI1 PIN_TWI_TWD1, PIN_TWI_TWCK1
/// USART0
#define PIN_USART0_RXD {0x1 << 19, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART0_TXD {0x1 << 18, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART0_CTS {0x1 << 8, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART0_RTS {0x1 << 7, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART0_SCK {0x1 << 17, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
/// USART1
#define PIN_USART1_RXD {0x1 << 21, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART1_TXD {0x1 << 22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART1_CTS {0x1 << 25, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART1_RTS {0x1 << 24, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_USART1_EN {0x1 << 23, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/// USB VBus monitoring pin definition.
#ifdef BOARD_REV_A
#define PIN_USB_VBUS {1 << 23, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
#endif
#ifdef BOARD_REV_B
#define PIN_USB_VBUS {1 << 21, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par sam3s_ek_extcomp "SAM3S-EK - External components"
/// This page lists the definitions related to external on-board components
/// located in the board.h file for the AT91SAM3S-EK.
///
/// !AT45 Dataflash Card
/// - BOARD_AT45_A_SPI_BASE
/// - BOARD_AT45_A_SPI_ID
/// - BOARD_AT45_A_SPI_PINS
/// - BOARD_AT45_A_SPI
/// - BOARD_AT45_A_NPCS
/// - BOARD_AT45_A_NPCS_PIN
///
/// !AT45 Dataflash (serial onboard DataFlash)
/// - BOARD_AT45_B_SPI_BASE
/// - BOARD_AT45_B_SPI_ID
/// - BOARD_AT45_B_SPI_PINS
/// - BOARD_AT45_B_SPI
/// - BOARD_AT45_B_NPCS
/// - BOARD_AT45_B_NPCS_PIN
///
/// !AT26 Serial Flash
/// - BOARD_AT26_A_SPI_BASE
/// - BOARD_AT26_A_SPI_ID
/// - BOARD_AT26_A_SPI_PINS
/// - BOARD_AT26_A_SPI
/// - BOARD_AT26_A_NPCS
/// - BOARD_AT26_A_NPCS_PIN
///
/// !SD Card
/// - MCI2_INTERFACE
/// - BOARD_SD_MCI_BASE
/// - BOARD_SD_MCI_ID
/// - BOARD_SD_PINS
/// - BOARD_SD_SLOT
///
/// !PSRAM
/// - BOARD_PSRAM_PINS
///
/// !LCD
/// - BOARD_LCD_ILI9325
/// - BOARD_LCD_PINS
/// - BOARD_BACKLIGHT_PIN
/// - BOARD_LCD_BASE
/// - BOARD_LCD_RS
/// - BOARD_LCD_WIDTH
/// - BOARD_LCD_HEIGHT
///
/// !TouchScreen
/// - BOARD_TSC_ADS7843
/// - PIN_TCS_IRQ
/// - PIN_TCS_BUSY
/// - BOARD_TSC_SPI_BASE
/// - BOARD_TSC_SPI_ID
/// - BOARD_TSC_SPI_PINS
/// - BOARD_TSC_NPCS
/// - BOARD_TSC_NPCS_PIN
///
/// Base address of SPI peripheral connected to the dataflash.
//#define BOARD_AT45_A_SPI_BASE SPI0
///// Identifier of SPI peripheral connected to the dataflash.
//#define BOARD_AT45_A_SPI_ID ID_SPI0
///// Pins of the SPI peripheral connected to the dataflash.
//#define BOARD_AT45_A_SPI_PINS PINS_SPI0
///// Dataflahs SPI number.
//#define BOARD_AT45_A_SPI 0
///// Chip select connected to the dataflash.
//#define BOARD_AT45_A_NPCS 3
///// Chip select pin connected to the dataflash.
//#define BOARD_AT45_A_NPCS_PIN PIN_SPI0_NPCS3
/// Base address of SPI peripheral connected to the dataflash.
//#define BOARD_AT45_B_SPI_BASE SPI1
///// Identifier of SPI peripheral connected to the dataflash.
//#define BOARD_AT45_B_SPI_ID ID_SPI1
///// Pins of the SPI peripheral connected to the dataflash.
//#define BOARD_AT45_B_SPI_PINS PINS_SPI1
///// Dataflahs SPI number.
//#define BOARD_AT45_B_SPI 1
///// Chip select connected to the dataflash.
//#define BOARD_AT45_B_NPCS 3
///// Chip select pin connected to the dataflash.
//#define BOARD_AT45_B_NPCS_PIN PIN_SPI1_NPCS3
/// Base address of SPI peripheral connected to the serialflash.
//#define BOARD_AT26_A_SPI_BASE SPI0
///// Identifier of SPI peripheral connected to the serialflash.
//#define BOARD_AT26_A_SPI_ID ID_SPI0
///// Pins of the SPI peripheral connected to the serialflash.
//#define BOARD_AT26_A_SPI_PINS PINS_SPI0
///// Serialflash SPI number.
//#define BOARD_AT26_A_SPI 0
///// Chip select connected to the serialflash.
//#define BOARD_AT26_A_NPCS 3
///// Chip select pin connected to the serialflash.
//#define BOARD_AT26_A_NPCS_PIN PIN_SPI0_NPCS3
/// ISO7816
/// - PIN_SMARTCARD_CONNECT
/// - PIN_ISO7816_RSTMC
/// - PINS_ISO7816
/// Smartcard detection pin
//#define PIN_SMARTCARD_CONNECT {1 << 5, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
/// PIN used for reset the smartcard
//#define PIN_ISO7816_RSTMC {1 << 7, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
/// Pins used for connect the smartcard
//#define PINS_ISO7816 PIN_USART0_TXD, PIN_USART0_SCK, PIN_ISO7816_RSTMC
/// Dma channel number
#define BOARD_MCI_DMA_CHANNEL 0
/// MCI0 DMA hardware handshaking ID
#define DMA_HW_SRC_REQ_ID_MCI0 AT91C_HDMA_SRC_PER_0
#define DMA_HW_DEST_REQ_ID_MCI0 AT91C_HDMA_DST_PER_0
/// MCI1 DMA hardware handshaking ID
#define DMA_HW_SRC_REQ_ID_MCI1 AT91C_HDMA_SRC_PER_13
#define DMA_HW_DEST_REQ_ID_MCI1 AT91C_HDMA_DST_PER_13
/// SD DMA hardware handshaking ID
#define BOARD_SD_DMA_HW_SRC_REQ_ID DMA_HW_SRC_REQ_ID_MCI0
#define BOARD_SD_DMA_HW_DEST_REQ_ID DMA_HW_DEST_REQ_ID_MCI0
/// HS MCI interface
#define MCI2_INTERFACE
/// Base address of the MCI peripheral connected to the SD card.
#define BOARD_SD_MCI_BASE MCI0//MCI
#if 0
// TODO check BSS
///// Peripheral identifier of the MCI connected to the SD card.
#define BOARD_SD_MCI_ID ID_MCI0 //ID_MCI
#endif
///// MCI pins that shall be configured to access the SD card.
#define BOARD_SD_PINS PINS_MCI
///// MCI slot to which the SD card is connected to.
#define BOARD_SD_SLOT MCI_SD_SLOTA
///// MCI Card Detect pin.
#define BOARD_SD_PIN_CD PIN_MCI_CD
/*#define BOARD_PSRAM_PINS PIN_EBI_DATA_BUS, PIN_EBI_NCS0, PIN_EBI_NRD, PIN_EBI_NWE, \
PIN_EBI_PSRAM_ADDR_BUS, PIN_EBI_PSRAM_NBS, PIN_EBI_A1 */
/** Indicates board has an ILI9325 external component to manage LCD. */
#define BOARD_LCD_ILI9325
/** LCD pins definition. */
#define BOARD_LCD_PINS PIN_EBI_DATA_BUS, PIN_EBI_NRD, PIN_EBI_NWE, \
PIN_EBI_NCS1, PIN_EBI_LCD_RS
/** Backlight pin definition. */
#define BOARD_BACKLIGHT_PIN {1 << 13, PIOC, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT}
/** Define ILI9325 base address. */
#define BOARD_LCD_BASE 0x61000000
/** Define ILI9325 register select signal. */
#define BOARD_LCD_RS (1 << 1)
/** Display width in pixels. */
#define BOARD_LCD_WIDTH 240
/** Display height in pixels. */
#define BOARD_LCD_HEIGHT 320
/** Indicates board has an ADS7843 external component to manage Touch Screen */
#define BOARD_TSC_ADS7843
#ifdef BOARD_REV_A
/** Touchscreen controller IRQ pin definition. */
#define PIN_TCS_IRQ {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_DEBOUNCE | PIO_IT_AIME | PIO_IT_EDGE}
#define PIN_TCS_IRQ_WUP_ID (1 << 3)
/** Touchscreen controller Busy pin definition. */
#define PIN_TCS_BUSY {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
#endif
#ifdef BOARD_REV_B
/** Touchscreen controller IRQ pin definition. */
#define PIN_TCS_IRQ {PIO_PA16, PIOA, ID_PIOA, PIO_INPUT, PIO_DEBOUNCE | PIO_IT_AIME | PIO_IT_EDGE}
#define PIN_TCS_IRQ_WUP_ID (1 << 15)
/** Touchscreen controller Busy pin definition. */
#define PIN_TCS_BUSY {PIO_PA17, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
#endif
/** Base address of SPI peripheral connected to the touchscreen controller. */
#define BOARD_TSC_SPI_BASE SPI
/** Identifier of SPI peripheral connected to the touchscreen controller. */
#define BOARD_TSC_SPI_ID ID_SPI
/** Pins of the SPI peripheral connected to the touchscreen controller. */
#define BOARD_TSC_SPI_PINS PINS_SPI
/** Chip select connected to the touchscreen controller. */
#define BOARD_TSC_NPCS 0
/** Chip select pin connected to the touchscreen controller. */
#define BOARD_TSC_NPCS_PIN PIN_SPI_NPCS0_PA11
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par sam3s_ek_mem "SAM3S-EK - Memories"
/// This page lists definitions related to internal & external on-board memories.
///
/// !Embedded Flash
/// - BOARD_FLASH_EFC
/// Internal SRAM address
#define AT91C_ISRAM AT91C_IRAM
#define AT91C_ISRAM_SIZE 0x00008000
#define AT91C_IFLASH_SIZE (0x40000)
#define AT91C_IFLASH_PAGE_SIZE (256) // Internal FLASH 0 Page Size: 256 bytes
#define AT91C_IFLASH_NB_OF_PAGES (1024) // Internal FLASH 0 Number of Pages: 512
#define AT91C_IFLASH_LOCK_REGION_SIZE (16384) // Internal FLASH 0 Lock Region Size: 16 Kbytes
#define AT91C_IFLASH_NB_OF_LOCK_BITS (16) // Internal FLASH 0 Number of Lock Bits: 16
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \section sam3s_ek_extcomp "SAM3S-EK - External components"
/// This page lists the definitions related to external on-board components
/// located in the board.h file for the SAM3S-EK.
///
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \par sam3s_ek_chipdef "SAM3S-EK - Individual chip definition"
/// This page lists the definitions related to different chip's definition
/// located in the board.h file for the SAM3S-EK.
/// DBGU
#define BOARD_DBGU_ID ID_DBGU
/// Rtc
#define BOARD_RTC_ID ID_RTC
/// Twi eeprom
#define BOARD_ID_TWI_EEPROM ID_TWI1
#define BOARD_BASE_TWI_EEPROM TWI1
#define BOARD_PINS_TWI_EEPROM PINS_TWI1
/// USART
#define BOARD_PIN_USART_RXD PIN_USART1_RXD
#define BOARD_PIN_USART_TXD PIN_USART1_TXD
#define BOARD_PIN_USART_CTS PIN_USART1_CTS
#define BOARD_PIN_USART_RTS PIN_USART1_RTS
#define BOARD_PIN_USART_EN PIN_USART1_EN
#define BOARD_USART_BASE USART1
#define BOARD_ID_USART ID_USART1
//------------------------------------------------------------------------------
#define PIN_EBI_NANDOE {1 << 9, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NANDWE {1 << 10, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NANDCLE {1 << 17, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NANDALE {1 << 16, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
#define PIN_EBI_NANDIO {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
/// Nandflash chip enable pin definition.
#define BOARD_NF_CE_PIN {1 << 14, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
/// Nandflash ready/busy pin definition.
#define BOARD_NF_RB_PIN {1 << 18, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP}
/// Nandflash controller peripheral pins definition.
#define PINS_NANDFLASH PIN_EBI_NANDIO, BOARD_NF_CE_PIN, BOARD_NF_RB_PIN, PIN_EBI_NANDOE, \
PIN_EBI_NANDWE, PIN_EBI_NANDCLE, PIN_EBI_NANDALE
/// Address for transferring command bytes to the nandflash.
#define BOARD_NF_COMMAND_ADDR 0x60400000
/// Address for transferring address bytes to the nandflash.
#define BOARD_NF_ADDRESS_ADDR 0x60200000
/// Address for transferring data bytes to the nandflash.
#define BOARD_NF_DATA_ADDR 0x60000000
#endif //#ifndef BOARD_H
@@ -0,0 +1,143 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include "board.h"
#include <cmsis/core_cm3.h>
#include "exceptions.h"
#include "board_lowlevel.h"
/*------------------------------------------------------------------------------
* Types
*------------------------------------------------------------------------------*/
typedef union { IntFunc __fun; void * __ptr; } IntVector;
/*------------------------------------------------------------------------------
* ProtoTypes
*------------------------------------------------------------------------------*/
extern void __iar_program_start( void );
int __low_level_init( void );
/*------------------------------------------------------------------------------
* Variables
*------------------------------------------------------------------------------*/
extern unsigned int __ICFEDIT_vector_start__;
/*------------------------------------------------------------------------------
* Exception Table
*------------------------------------------------------------------------------*/
#pragma language=extended
#pragma segment="CSTACK"
/* The name "__vector_table" has special meaning for C-SPY: */
/* it is where the SP start value is found, and the NVIC vector */
/* table register (VTOR) is initialized to this address if != 0. */
#pragma section = ".vectors"
#pragma location = ".vectors"
const IntVector __vector_table[] =
{
{ .__ptr = __sfe( "CSTACK" ) },
__iar_program_start,
NMI_Handler,
HardFault_Handler,
MemManage_Handler,
BusFault_Handler,
UsageFault_Handler,
0, 0, 0, 0, /* Reserved */
SVC_Handler,
DebugMon_Handler,
0, /* Reserved */
PendSV_Handler,
SysTick_Handler,
/* Configurable interrupts */
SUPC_IrqHandler, /* 0 SUPPLY CONTROLLER */
RSTC_IrqHandler, /* 1 RESET CONTROLLER */
RTC_IrqHandler, /* 2 REAL TIME CLOCK */
RTT_IrqHandler, /* 3 REAL TIME TIMER */
WDT_IrqHandler, /* 4 WATCHDOG TIMER */
PMC_IrqHandler, /* 5 PMC */
EEFC_IrqHandler, /* 6 EEFC */
IrqHandlerNotUsed, /* 7 Reserved */
UART0_IrqHandler, /* 8 UART0 */
UART1_IrqHandler, /* 9 UART1 */
SMC_IrqHandler, /* 10 SMC */
PIOA_IrqHandler, /* 11 Parallel IO Controller A */
PIOB_IrqHandler, /* 12 Parallel IO Controller B */
PIOC_IrqHandler, /* 13 Parallel IO Controller C */
USART0_IrqHandler, /* 14 USART 0 */
USART1_IrqHandler, /* 15 USART 1 */
IrqHandlerNotUsed, /* 16 Reserved */
IrqHandlerNotUsed, /* 17 Reserved */
MCI_IrqHandler, /* 18 MCI */
TWI0_IrqHandler, /* 19 TWI 0 */
TWI1_IrqHandler, /* 20 TWI 1 */
SPI_IrqHandler, /* 21 SPI */
SSC_IrqHandler, /* 22 SSC */
TC0_IrqHandler, /* 23 Timer Counter 0 */
TC1_IrqHandler, /* 24 Timer Counter 1 */
TC2_IrqHandler, /* 25 Timer Counter 2 */
TC3_IrqHandler, /* 26 Timer Counter 3 */
TC4_IrqHandler, /* 27 Timer Counter 4 */
TC5_IrqHandler, /* 28 Timer Counter 5 */
ADC_IrqHandler, /* 29 ADC controller */
DAC_IrqHandler, /* 30 DAC controller */
PWM_IrqHandler, /* 31 PWM */
CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
ACC_IrqHandler, /* 33 Analog Comparator */
USBD_IrqHandler, /* 34 USB Device Port */
IrqHandlerNotUsed /* 35 not used */
};
/*------------------------------------------------------------------------------
* Exception Table
*------------------------------------------------------------------------------*/
/**------------------------------------------------------------------------------
* This is the code that gets called on processor reset. To initialize the
* device.
*------------------------------------------------------------------------------*/
int __low_level_init( void )
{
unsigned int * src = __section_begin(".vectors");
LowLevelInit();
SCB->VTOR = ((unsigned int)(src)) | (0x0 << 7);
return 1; /* if return 0, the data sections will not be initialized. */
}
@@ -0,0 +1,195 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* \par Purpose
*
* Provides the low-level initialization function that gets called on chip startup.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "board.h"
#include "board_memories.h"
#include "board_lowlevel.h"
#include <pio/pio.h>
/*----------------------------------------------------------------------------
* Local definitions
*----------------------------------------------------------------------------*/
/** Define clock timeout */
#define CLOCK_TIMEOUT 5000
/** Bit 29 must always be set to 1 when programming the CKGR_PLLAR register.*/
#define PMC_PLLA_SET_BIT29 (0x1 << 29)
/** Specifies the number of Slow Clock cycles x8 before the LOCKA bit is set in PMC_SR after CKGR_PLLAR is written.*/
#define PMC_PLLA_COUNT (0xBF << 8)
/** The PLLA Clock frequency is the PLLA input frequency multiplied by 8*/
#define PMC_PLLA_MULTIPIER (0x07 << 16)
/** PLLA Divider is bypassed.*/
#define PMC_PLLA_DIV (0x01)
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
static void BOARD_ConfigurePmc(void)
{
/* TODO: configurate PLL in new way */
#if 0
uint32_t timeout = 0;
/** 1: Checking the Main Oscillator Frequency (Optional) and Initialize main oscillator */
/** 1.1 Initialize main oscillator */
// TODO:
/** 2. Setting PLL and Divider*/
/** 2.1 Initialize PLLA*/
PMC->CKGR_PLLAR = ( PMC_PLLA_SET_BIT29 |
PMC_PLLA_MULTIPIER |
PMC_PLLA_COUNT |
PMC_PLLA_DIV
);
timeout = 0;
/** 2.2 Wait for the LOCKA bit to be set by polling the status register.*/
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
/** 2.3 wait for the MCKRDY bit to be set by polling the status register*/
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
/** 3. Selection of Master Clock and Processor Clock*/
PMC->PMC_MCKR |= PMC_MCKR_PRES_CLK_2;
/** 3.1 wait for the MCKRDY bit to be set by polling the status register*/
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
/** 3.2 PLLA Clock is selected */
PMC->PMC_MCKR = PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK;
/** 3.3 wait for the MCKRDY bit to be set by polling the status register*/
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
#endif
#if 1 // old as sam3u
#define AT91C_CKGR_MUL_SHIFT 16
#define AT91C_CKGR_OUT_SHIFT 14
#define AT91C_CKGR_PLLCOUNT_SHIFT 8
#define AT91C_CKGR_DIV_SHIFT 0
// Settings at 48/48MHz
#define BOARD_OSCOUNT (CKGR_MOR_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 ( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)
// Define clock timeout
#undef CLOCK_TIMEOUT
#define CLOCK_TIMEOUT 0xFFFFFFFF
uint32_t timeout = 0;
/* Enable NRST reset
************************************/
//AT91C_BASE_RSTC->RSTC_RMR |= AT91C_RSTC_URSTEN;
/* Select external slow clock
****************************/
if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST) {
SUPC->SUPC_CR = SUPC_CR_XTALSEL_CRYSTAL_SEL | ((uint32_t)0xA5 << 24);
timeout = 0;
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );
}
/* Initialize main oscillator
****************************/
if(!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL))
{
PMC->CKGR_MOR = (0x37 << 16) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
}
/* Switch to 3-20MHz Xtal oscillator */
PMC->CKGR_MOR = (0x37 << 16) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS) | PMC_MCKR_CSS_MAIN_CLK;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
/* Initialize PLLA */
PMC->CKGR_PLLAR = BOARD_PLLR;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
/* Initialize UTMI for USB usage, can be disabled if not using USB for the sake of saving power*/
//AT91C_BASE_CKGR->CKGR_UCKR |= (AT91C_CKGR_UPLLCOUNT & (3 << 20)) | AT91C_CKGR_UPLLEN;
//timeout = 0;
//while (!(PMC->PMC_SR & AT91C_PMC_LOCKU) && (timeout++ < CLOCK_TIMEOUT));
/* Switch to fast clock
**********************/
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS) | PMC_MCKR_CSS_MAIN_CLK;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
PMC->PMC_MCKR = BOARD_MCKR;
timeout = 0;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT));
#endif
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/**
* \brief Performs the low-level initialization of the chip. This includes EFC,
* master clock and watchdog configuration.
*/
/*----------------------------------------------------------------------------*/
void LowLevelInit (void)
{
/** Set 2 WS for Embedded Flash Access */
EFC->EEFC_FMR = (1 << 8);
/** Configure PMC */
BOARD_ConfigurePmc();
}
@@ -0,0 +1,49 @@
/* ----------------------------------------------------------------------------
* 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
///
/// Collection of methods for lowlevel.
///
//------------------------------------------------------------------------------
#ifndef BOARD_LOWLEVEL_H
#define BOARD_LOWLEVEL_H
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
extern void LowLevelInit(void);
extern void OptimizeCpuSpeed(void);
#endif // BOARD_LOWLEVEL_H
@@ -0,0 +1,96 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/*
Title: Memories implementation
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include "board_memories.h"
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Configures the EBI for NandFlash access.
*
*/
extern void BOARD_ConfigureNandFlash( void )
{
// Open EBI clock
PMC->PMC_PCER0 = (1<< ID_SMC);
// NCS0 is assigned to a NAND Flash (NANDOE and NANWE used for NCS0)
MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SMC_NFCS0;
#if 0
SMC->SMC_CS_NUMBER[0].SMC_SETUP = 0
| ((0 << 0) & SMC_SETUP0_NWE_SETUP)
| ((1 << 8) & SMC_SETUP0_NCS_WR_SETUP)
| ((0 << 16) & SMC_SETUP0_NRD_SETUP)
| ((1 << 24) & SMC_SETUP0_NCS_RD_SETUP);
SMC->SMC_CS_NUMBER[0].SMC_PULSE = 0
| ((2 << 0) & SMC_PULSE0_NWE_PULSE)
| ((3 << 8) & SMC_PULSE0_NCS_WR_PULSE)
| ((4 << 16) & SMC_PULSE0_NRD_PULSE)
| ((4 << 24) & SMC_PULSE0_NCS_RD_PULSE);
SMC->SMC_CS_NUMBER[0].SMC_CYCLE = 0
| ((4 << 0) & SMC_CYCLE0_NWE_CYCLE)
| ((7 << 16) & SMC_CYCLE0_NRD_CYCLE);
SMC->SMC_CS_NUMBER[0].SMC_MODE = SMC_MODE0_READ_MODE | SMC_MODE0_WRITE_MODE;
#else
SMC->SMC_CS_NUMBER[0].SMC_SETUP = 0
| ((0 << 0) & SMC_SETUP0_NWE_SETUP)
| ((0 << 8) & SMC_SETUP0_NCS_WR_SETUP)
| ((0 << 16) & SMC_SETUP0_NRD_SETUP)
| ((0 << 24) & SMC_SETUP0_NCS_RD_SETUP);
SMC->SMC_CS_NUMBER[0].SMC_PULSE = 0
| ((2 << 0) & SMC_PULSE0_NWE_PULSE)
| ((2 << 8) & SMC_PULSE0_NCS_WR_PULSE)
| ((2 << 16) & SMC_PULSE0_NRD_PULSE)
| ((2 << 24) & SMC_PULSE0_NCS_RD_PULSE);
SMC->SMC_CS_NUMBER[0].SMC_CYCLE = 0
| ((3 << 0) & SMC_CYCLE0_NWE_CYCLE)
| ((3 << 16) & SMC_CYCLE0_NRD_CYCLE);
SMC->SMC_CS_NUMBER[0].SMC_MODE = SMC_MODE1_READ_MODE | SMC_MODE1_WRITE_MODE;
#endif
}
@@ -0,0 +1,49 @@
/* ----------------------------------------------------------------------------
* 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
///
///
/// !Usage
///
//------------------------------------------------------------------------------
#ifndef BOARD_MEMORIES_H
#define BOARD_MEMORIES_H
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
extern void BOARD_ConfigureNandFlash( void ) ;
#endif //#ifndef BOARD_MEMORIES_H
+385
View File
@@ -0,0 +1,385 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
* This file contains the default exception handlers.
*
* \note
* The exception handler has weak aliases.
* As they are weak aliases, any function with the same name will override
* this definition.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "exceptions.h"
#include <board.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Default interrupt handler for not used irq.
*/
void IrqHandlerNotUsed(void)
{
while(1);
}
/**
* \brief Default NMI interrupt handler.
*/
WEAK void NMI_Handler(void)
{
while(1);
}
/**
* \brief Default HardFault interrupt handler.
*/
WEAK void HardFault_Handler(void)
{
while(1);
}
/**
* \brief Default MemManage interrupt handler.
*/
WEAK void MemManage_Handler(void)
{
while(1);
}
/**
* \brief Default BusFault interrupt handler.
*/
WEAK void BusFault_Handler(void)
{
while(1);
}
/**
* \brief Default UsageFault interrupt handler.
*/
WEAK void UsageFault_Handler(void)
{
while(1);
}
/**
* \brief Default SVC interrupt handler.
*/
WEAK void SVC_Handler(void)
{
while(1);
}
/**
* \brief Default DebugMon interrupt handler.
*/
WEAK void DebugMon_Handler(void)
{
while(1);
}
/**
* \brief Default PendSV interrupt handler.
*/
WEAK void PendSV_Handler(void)
{
while(1);
}
/**
* \brief Default SysTick interrupt handler.
*/
WEAK void SysTick_Handler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for Supply Controller.
*/
WEAK void SUPC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for Reset Controller.
*/
WEAK void RSTC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for Real Time Clock.
*/
WEAK void RTC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for Real Time Timer.
*/
WEAK void RTT_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for Watchdog Timer.
*/
WEAK void WDT_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for PMC.
*/
WEAK void PMC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for EEFC.
*/
WEAK void EEFC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for UART0.
*/
WEAK void UART0_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for UART1.
*/
WEAK void UART1_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for SMC.
*/
WEAK void SMC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for PIOA Controller.
*/
WEAK void PIOA_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for PIOB Controller.
*/
WEAK void PIOB_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for PIOC Controller.
*/
WEAK void PIOC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for USART0.
*/
WEAK void USART0_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for USART1.
*/
WEAK void USART1_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for MCI.
*/
WEAK void MCI_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for TWI0.
*/
WEAK void TWI0_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for TWI1.
*/
WEAK void TWI1_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for SPI.
*/
WEAK void SPI_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for SSC.
*/
WEAK void SSC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for TC0.
*/
WEAK void TC0_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for TC1.
*/
WEAK void TC1_IrqHandler(void)
{
while(1);
}
/**
* \brief Default interrupt handler for TC2.
*/
WEAK void TC2_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for TC3.
*/
WEAK void TC3_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for TC4.
*/
WEAK void TC4_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for TC5.
*/
WEAK void TC5_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for ADC.
*/
WEAK void ADC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for DAC.
*/
WEAK void DAC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for PWM.
*/
WEAK void PWM_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for CRCCU.
*/
WEAK void CRCCU_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for ACC.
*/
WEAK void ACC_IrqHandler(void)
{
while(1);
}
/**
* \brief Default SUPC interrupt handler for USBD.
*/
WEAK void USBD_IrqHandler(void)
{
while(1);
}
+103
View File
@@ -0,0 +1,103 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
* Interface for default exception handlers.
*/
#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/* Function prototype for exception table items (interrupt handler). */
typedef void( *IntFunc )( void );
/* Define WEAK attribute */
#if defined ( __CC_ARM )
#define WEAK __attribute__ ((weak))
#elif defined ( __ICCARM__ )
#define WEAK __weak
#elif defined ( __GNUC__ )
#define WEAK __attribute__ ((weak))
#endif
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void IrqHandlerNotUsed(void);
extern WEAK void NMI_Handler( void );
extern WEAK void HardFault_Handler( void );
extern WEAK void MemManage_Handler( void );
extern WEAK void BusFault_Handler( void );
extern WEAK void UsageFault_Handler( void );
extern WEAK void SVC_Handler( void );
extern WEAK void DebugMon_Handler( void );
extern WEAK void PendSV_Handler( void );
extern WEAK void SysTick_Handler( void );
extern WEAK void SUPC_IrqHandler(void);
extern WEAK void RSTC_IrqHandler(void);
extern WEAK void RTC_IrqHandler(void);
extern WEAK void RTT_IrqHandler(void);
extern WEAK void WDT_IrqHandler(void);
extern WEAK void PMC_IrqHandler(void);
extern WEAK void EEFC_IrqHandler(void);
extern WEAK void UART0_IrqHandler(void);
extern WEAK void UART1_IrqHandler(void);
extern WEAK void SMC_IrqHandler(void);
extern WEAK void PIOA_IrqHandler(void);
extern WEAK void PIOB_IrqHandler(void);
extern WEAK void PIOC_IrqHandler(void);
extern WEAK void USART0_IrqHandler(void);
extern WEAK void USART1_IrqHandler(void);
extern WEAK void MCI_IrqHandler(void);
extern WEAK void TWI0_IrqHandler(void);
extern WEAK void TWI1_IrqHandler(void);
extern WEAK void SPI_IrqHandler(void);
extern WEAK void SSC_IrqHandler(void);
extern WEAK void TC0_IrqHandler(void);
extern WEAK void TC1_IrqHandler(void);
extern WEAK void TC2_IrqHandler(void);
extern WEAK void TC3_IrqHandler(void);
extern WEAK void TC4_IrqHandler(void);
extern WEAK void TC5_IrqHandler(void);
extern WEAK void ADC_IrqHandler(void);
extern WEAK void DAC_IrqHandler(void);
extern WEAK void PWM_IrqHandler(void);
extern WEAK void CRCCU_IrqHandler(void);
extern WEAK void ACC_IrqHandler(void);
extern WEAK void USBD_IrqHandler(void);
#endif /* #ifndef EXCEPTIONS_H */
+804
View File
@@ -0,0 +1,804 @@
/******************************************************************************
* @file: core_cm3.c
* @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version: V1.10
* @date: 24. Feb. 2009
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for armcc */
#define __INLINE __inline /*!< inline keyword for armcc */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for iarcc */
#define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */
#define __nop __no_operation /*!< no operation intrinsic in iarcc */
#elif defined ( __GNUC__ )
#define __ASM asm /*!< asm keyword for gcc */
#define __INLINE inline /*!< inline keyword for gcc */
#endif
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/**
* @brief Return the Process Stack Pointer
*
* @param none
* @return uint32_t ProcessStackPointer
*
* Return the actual process stack pointer
*/
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
/**
* @brief Set the Process Stack Pointer
*
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
/**
* @brief Return the Main Stack Pointer
*
* @param none
* @return uint32_t Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
/**
* @brief Set the Main Stack Pointer
*
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param uint16_t value to reverse
* @return uint32_t reversed value
*
* Reverse byte order in unsigned short value
*/
__ASM uint32_t __REV16(uint16_t value)
{
rev16 r0, r0
bx lr
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param int16_t value to reverse
* @return int32_t reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
__ASM int32_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#if (__ARMCC_VERSION < 400000)
/**
* @brief Remove the exclusive lock created by ldrex
*
* @param none
* @return none
*
* Removes the exclusive lock which is created by ldrex.
*/
__ASM void __CLREX(void)
{
clrex
}
/**
* @brief Return the Base Priority value
*
* @param none
* @return uint32_t BasePriority
*
* Return the content of the base priority register
*/
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
/**
* @brief Set the Base Priority value
*
* @param uint32_t BasePriority
* @return none
*
* Set the base priority register
*/
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
/**
* @brief Return the Priority Mask value
*
* @param none
* @return uint32_t PriMask
*
* Return the state of the priority mask bit from the priority mask
* register
*/
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
/**
* @brief Set the Priority Mask value
*
* @param uint32_t PriMask
* @return none
*
* Set the priority mask bit in the priority mask register
*/
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
/**
* @brief Return the Fault Mask value
*
* @param none
* @return uint32_t FaultMask
*
* Return the content of the fault mask register
*/
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
/**
* @brief Set the Fault Mask value
*
* @param uint32_t faultMask value
* @return none
*
* Set the fault mask register
*/
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
/**
* @brief Return the Control Register value
*
* @param none
* @return uint32_t Control value
*
* Return the content of the control register
*/
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
/**
* @brief Set the Control Register value
*
* @param uint32_t Control value
* @return none
*
* Set the control register
*/
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
#pragma diag_suppress=Pe940
/**
* @brief Return the Process Stack Pointer
*
* @param none
* @return uint32_t ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
__ASM("bx lr");
}
/**
* @brief Set the Process Stack Pointer
*
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
__ASM("bx lr");
}
/**
* @brief Return the Main Stack Pointer
*
* @param none
* @return uint32_t Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
__ASM("bx lr");
}
/**
* @brief Set the Main Stack Pointer
*
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
__ASM("bx lr");
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param uint16_t value to reverse
* @return uint32_t reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
__ASM("rev16 r0, r0");
__ASM("bx lr");
}
/**
* @brief Reverse bit order of value
*
* @param uint32_t value to reverse
* @return uint32_t reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive
*
* @param uint8_t* address
* @return uint8_t value of (*address)
*
* Exclusive LDR command
*/
uint8_t __LDREXB(uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive
*
* @param uint16_t* address
* @return uint16_t value of (*address)
*
* Exclusive LDR command
*/
uint16_t __LDREXH(uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive
*
* @param uint32_t* address
* @return uint32_t value of (*address)
*
* Exclusive LDR command
*/
uint32_t __LDREXW(uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive
*
* @param uint8_t *address
* @param uint8_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive
*
* @param uint16_t *address
* @param uint16_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive
*
* @param uint32_t *address
* @param uint32_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
__ASM("bx lr");
}
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/**
* @brief Return the Process Stack Pointer
*
* @param none
* @return uint32_t ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, psp" : "=r" (result) );
return(result);
}
/**
* @brief Set the Process Stack Pointer
*
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) );
}
/**
* @brief Return the Main Stack Pointer
*
* @param none
* @return uint32_t Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, msp" : "=r" (result) );
return(result);
}
/**
* @brief Set the Main Stack Pointer
*
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) );
}
/**
* @brief Return the Base Priority value
*
* @param none
* @return uint32_t BasePriority
*
* Return the content of the base priority register
*/
uint32_t __get_BASEPRI(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/**
* @brief Set the Base Priority value
*
* @param uint32_t BasePriority
* @return none
*
* Set the base priority register
*/
void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/**
* @brief Return the Priority Mask value
*
* @param none
* @return uint32_t PriMask
*
* Return the state of the priority mask bit from the priority mask
* register
*/
uint32_t __get_PRIMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Priority Mask value
*
* @param uint32_t PriMask
* @return none
*
* Set the priority mask bit in the priority mask register
*/
void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
/**
* @brief Return the Fault Mask value
*
* @param none
* @return uint32_t FaultMask
*
* Return the content of the fault mask register
*/
uint32_t __get_FAULTMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Fault Mask value
*
* @param uint32_t faultMask value
* @return none
*
* Set the fault mask register
*/
void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
/**
* @brief Reverse byte order in integer value
*
* @param uint32_t value to reverse
* @return uint32_t reversed value
*
* Reverse byte order in integer value
*/
uint32_t __REV(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param uint16_t value to reverse
* @return uint32_t reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
uint32_t result=0;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param int32_t value to reverse
* @return int32_t reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
int32_t __REVSH(int16_t value)
{
uint32_t result=0;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse bit order of value
*
* @param uint32_t value to reverse
* @return uint32_t reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief LDR Exclusive
*
* @param uint8_t* address
* @return uint8_t value of (*address)
*
* Exclusive LDR command
*/
uint8_t __LDREXB(uint8_t *addr)
{
uint8_t result=0;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive
*
* @param uint16_t* address
* @return uint16_t value of (*address)
*
* Exclusive LDR command
*/
uint16_t __LDREXH(uint16_t *addr)
{
uint16_t result=0;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive
*
* @param uint32_t* address
* @return uint32_t value of (*address)
*
* Exclusive LDR command
*/
uint32_t __LDREXW(uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief STR Exclusive
*
* @param uint8_t *address
* @param uint8_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive
*
* @param uint16_t *address
* @param uint16_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive
*
* @param uint32_t *address
* @param uint32_t value to store
* @return uint32_t successful / failed
*
* Exclusive STR command
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief Return the Control Register value
*
* @param none
* @return uint32_t Control value
*
* Return the content of the control register
*/
uint32_t __get_CONTROL(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/**
* @brief Set the Control Register value
*
* @param uint32_t Control value
* @return none
*
* Set the control register
*/
void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,212 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of ADS7843 driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
#ifdef BOARD_TSC_ADS7843
#include <pio/pio.h>
#include <spi/spi.h>
#include "ads7843.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#define ADS_CTRL_PD0 (1 << 0) /* PD0 */
#define ADS_CTRL_PD1 (1 << 1) /* PD1 */
#define ADS_CTRL_DFR (1 << 2) /* SER/DFR */
#define ADS_CTRL_EIGHT_BITS_MOD (1 << 3) /* Mode */
#define ADS_CTRL_START (1 << 7) /* Start Bit */
#define ADS_CTRL_SWITCH_SHIFT 4 /* Address setting */
#if (BOARD_LCD_WIDTH == 240)
/* Get X position command */
#define CMD_Y_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
/* Get Y position command */
#define CMD_X_POSITION ((5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
#else
/* Get X position command */
#define CMD_X_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
/* Get Y position command */
#define CMD_Y_POSITION ((5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
#endif
/* Enable penIRQ */
#define CMD_ENABLE_PENIRQ ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START)
#define ADS7843_TIMEOUT 5000000
#define DELAY_BEFORE_SPCK (200 << 16) /* 2us min (tCSS) <=> 200/100 000 000 = 2us */
#define DELAY_BETWEEN_CONS_COM (0xf << 24) /* 5us min (tCSH) <=> (32 * 15) / (100 000 000) = 5us */
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** Pins used by SPI */
static const Pin pinsSPI[] = {BOARD_TSC_SPI_PINS, BOARD_TSC_NPCS_PIN};
/** Touch screen BUSY pin */
static const Pin pinBusy[] = {PIN_TCS_BUSY};
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Generic function to send a command to the touchscreen controller.
*
* \param bCmd command to send
*
* \return command result
*/
static uint32_t SendCommand(unsigned char bCmd)
{
uint32_t uResult = 0;
uint32_t uTimeout = 0;
/* (volatile declaration needed for code optimisation by compiler) */
volatile unsigned char bufferRX[3];
volatile unsigned char bufferTX[3];
Pdc *pPdc = (Pdc *)SPI;
uint32_t dStatus;
bufferRX[0] = 0;
bufferRX[1] = 0;
bufferRX[2] = 0;
bufferTX[0] = bCmd;
bufferTX[1] = 0;
bufferTX[2] = 0;
/* Send Command and data through the SPI */
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
pPdc->PERIPH_RPR = (uint32_t) bufferRX;
pPdc->PERIPH_RCR = 3;
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
pPdc->PERIPH_TPR = (uint32_t) bufferTX;
pPdc->PERIPH_TCR = 3;
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTEN;
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTEN;
do {
dStatus = REG_SPI_SR;
uTimeout++;
}
while ((( dStatus & SPI_SR_RXBUFF) != SPI_SR_RXBUFF) && (uTimeout < ADS7843_TIMEOUT));
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
uResult = ((uint32_t)bufferRX[1] << 8) | (uint32_t)bufferRX[2];
uResult = uResult >> 4;
return uResult;
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Get position of the pen by ask the ADS controller (SPI).
*
* \param px_pos pointer to the horizontal position
* \param py_pos pointer to the vertical position
*
*/
void ADS7843_GetPosition(uint32_t *px_pos, uint32_t *py_pos)
{
/* Get X position */
*px_pos = SendCommand(CMD_X_POSITION);
/* Get Y position */
*py_pos = SendCommand(CMD_Y_POSITION);
/* Switch to full power mode */
SendCommand(CMD_ENABLE_PENIRQ);
}
/**
* \brief Initialization of the SPI for communication with ADS7843 component.
*/
void ADS7843_Initialize(void)
{
volatile uint32_t uDummy;
/* Configure pins */
PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI));
PIO_Configure(pinBusy, PIO_LISTSIZE(pinBusy));
SPI_Configure(BOARD_TSC_SPI_BASE,
BOARD_TSC_SPI_ID,
SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) /* Value of the SPI configuration register. */
);
SPI_ConfigureNPCS(BOARD_TSC_SPI_BASE, BOARD_TSC_NPCS,
SPI_CSR_NCPHA | (SPI_CSR_DLYBS & DELAY_BEFORE_SPCK) |
(SPI_CSR_DLYBCT & DELAY_BETWEEN_CONS_COM) | (0xC8 << 8) );
SPI_Enable(BOARD_TSC_SPI_BASE);
for (uDummy=0; uDummy<100000; uDummy++);
uDummy = REG_SPI_SR;
uDummy = REG_SPI_RDR;
SendCommand(CMD_ENABLE_PENIRQ);
}
/**
* \brief Reset the ADS7843
*/
void ADS7843_Reset(void)
{
/* Disable SPI */
SPI_Disable(BOARD_TSC_SPI_BASE);
}
#endif /* #ifdef BOARD_TSC_ADS7843 */
@@ -0,0 +1,58 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for ADS7843 driver.
*/
#ifndef ADS7843_H
#define ADS7843_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#ifdef BOARD_TSC_ADS7843
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void ADS7843_Initialize(void);
extern void ADS7843_Reset(void);
extern void ADS7843_GetPosition(uint32_t *px_pos, uint32_t *py_pos);
#endif /* #ifdef BOARD_TSC_ADS7843 */
#endif /* #ifndef ADS7843_H */
@@ -0,0 +1,140 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation WM8731 driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "wm8731.h"
#include <board.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Read data from WM8731 Register.
*
* \param pTwid Pointer to twi driver structure
* \param device Twi slave address.
* \param regAddr Register address to read.
* \return value in the given register.
*/
uint16_t WM8731_Read(Twid *pTwid,
uint32_t device,
uint32_t regAddr)
{
uint16_t bitsDataRegister;
uint8_t Tdata[2]={0,0};
TWID_Read(pTwid, device, regAddr, 0, Tdata, 2, 0);
bitsDataRegister = (Tdata[0] << 8) | Tdata[1];
return bitsDataRegister;
}
/**
* \brief Write data to WM8731 Register.
*
* \param pTwid Pointer to twi driver structure
* \param device Twi slave address.
* \param regAddr Register address to read.
* \param data Data to write
*/
void WM8731_Write(Twid *pTwid,
uint32_t device,
uint32_t regAddr,
uint16_t data)
{
uint8_t tmpData[2];
uint16_t tmp;
tmp = ((regAddr & 0x7f) << 9) | (data & 0x1ff);
tmpData[0] = (tmp & 0xff00) >> 8;
tmpData[1] = tmp & 0xff;
TWID_Write(pTwid, device, regAddr, 0, tmpData, 2, 0);
}
/**
* \brief Init WM8731 to DAC mode.
*
* \param pTwid Pointer to twi driver structure
* \param device Twi slave address.
* \return 0.
*/
uint8_t WM8731_DAC_Init(Twid *pTwid,
uint32_t device)
{
/* reset */
WM8731_Write(pTwid, device, WM8731_REG_RESET, 0);
/* analogue audio path control */
WM8731_Write(pTwid, device, WM8731_REG_ANALOGUE_PATH_CTRL, 0x12);
/* digital audio path control*/
WM8731_Write(pTwid, device, WM8731_REG_DIGITAL_PATH_CTRL, 0x00);
/* power down control */
WM8731_Write(pTwid, device, WM8731_REG_PWDOWN_CTRL, 0x7);
/* Active control*/
WM8731_Write(pTwid, device, WM8731_REG_ACTIVE_CTRL, 0x01);
return 0;
}
/**
* \brief Set WM8731 volume
*
* \param pTwid Pointer to twi driver structure
* \param device Twi slave address.
* \param register Register address
* \param value Register value, valid value is between 0x30 to 0x7f
* \return 0.
*/
uint8_t WM8731_VolumeSet(Twid *pTwid,
uint32_t device,
uint16_t value)
{
uint16_t regValue;
value &= WM8731_LHPVOL_BITS;
regValue = WM8731_LRHPBOTH_BIT | WM8731_LZCEN_BIT | value;
WM8731_Write(pTwid, device, WM8731_REG_LEFT_HPOUT, regValue);
regValue = WM8731_RZCEN_BIT | WM8731_RLHPBOTH_BIT | value;
WM8731_Write(pTwid, device, WM8731_REG_RIGHT_HPOUT, value);
return 0;
}
@@ -0,0 +1,195 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation WM8731 driver.
*
*/
#ifndef WM8731_H
#define WM8731_H
#include "board.h"
#include <twi/twid.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#define WM8731_CSB_STATE (0x0 << 0)
/** Slave address */
//#define WM8731_SLAVE_ADDRESS 0x1a | WM8731_CSB_STATE*/
#define WM8731_SLAVE_ADDRESS 0x1b
/** Reset register*/
#define WM8731_REG_RESET 0x0F
/** Left Line in register*/
#define WM8731_REG_LEFT_lINEIN 0x0
/** Left line input volume control*/
#define WM8731_LINVOL_BITS (0x1f << 0)
/** Left line input mute to ADC*/
#define WM8731_LINMUTE_BIT (0x1 << 7)
/** Left to right channel line input volume and mute data load control*/
#define WM8731_LRINBOTH_BIT (0x0 << 8)
/** Right Line in register*/
#define WM8731_REG_RIGHT_lINEIN 0x1
/** Right line input volume control*/
#define WM8731_RINVOL_BITS (0x1f << 0)
/** Right line input mute to ADC*/
#define WM8731_RINMUTE_BIT (0x1 << 7)
/** Right to right channel line input volume and mute data load control*/
#define WM8731_RLINBOTH_BIT (0x0 << 8)
/** Left Headphone out register*/
#define WM8731_REG_LEFT_HPOUT 0x2
/** Left chnnel headphone output volume control*/
#define WM8731_LHPVOL_BITS (0x7f << 0)
/** Left channel zero cross detect enable*/
#define WM8731_LZCEN_BIT (0x1 << 7)
/** Left to right channel headphone volume, mute and zero cross data load control*/
#define WM8731_LRHPBOTH_BIT (0x1 << 8)
/** Right Headphone out register*/
#define WM8731_REG_RIGHT_HPOUT 0x3
/** Right chnnel headphone output volume control*/
#define WM8731_RHPVOL_BITS (0x7f << 0)
/** Right channel zero cross detect enable*/
#define WM8731_RZCEN_BIT (0x1 << 7)
/** Right to right channel headphone volume, mute and zero cross data load control*/
#define WM8731_RLHPBOTH_BIT (0x1 << 8)
/** Analogue audio path control register*/
#define WM8731_REG_ANALOGUE_PATH_CTRL 0x4
/** Digital audio path control register*/
#define WM8731_REG_DIGITAL_PATH_CTRL 0x5
/** Power down control register*/
#define WM8731_REG_PWDOWN_CTRL 0x6
/** LineIn power down*/
#define WM8731_LINEINPD_BIT (0x1 << 0)
#define WM8731_ENABLE_LINEINPD (0x1 << 0)
#define WM8731_DISABLE_LINEINPD (0x0 << 0)
/** Mic power down*/
#define WM8731_MICPD_BIT (0x1 << 1)
#define WM8731_ENABLE_MICPD (0x1 << 1)
#define WM8731_DISABLE_MICPD (0x0 << 1)
/** ADC power down*/
#define WM8731_ADCPD_BIT (0x1 << 2)
#define WM8731_ENABLE_ADCPD (0x1 << 2)
#define WM8731_DISABLE_ADCPD (0x0 << 2)
/** DAC power down*/
#define WM8731_DACPD_BIT (0x1 << 3)
#define WM8731_ENABLE_DACPD (0x1 << 3)
#define WM8731_DISABLE_DACPD (0x0 << 3)
/** OUT power down*/
#define WM8731_OUTPD_BIT (0x1 << 4)
#define WM8731_ENABLE_OUTPD (0x1 << 4)
#define WM8731_DISABLE_OUTPD (0x0 << 4)
/** OSC power down*/
#define WM8731_OSCBIT (0x1 << 5)
#define WM8731_ENABLE_OSCPD (0x1 << 5)
#define WM8731_DISABLE_OSCPD (0x0 << 5)
/** CLKOUT powerdown*/
#define WM8731_CLKOUTPD_BIT (0x1 << 6)
#define WM8731_ENABLE_CLKOUTPD (0x1 << 6)
#define WM8731_DISABLE_CLKOUTPD (0x0 << 6)
/** Power off device*/
#define WM8731_POWEROFF_BIT (0x1 << 7)
#define WM8731_DEV_POWER_OFF (0x1 << 7)
#define WM8731_DEV_POWER_ON (0x0 << 7)
/** Interface format register*/
#define WM8731_REG_DA_INTERFACE_FORMAT 0x7
/** Format*/
#define WM8731_FORMAT_BITS (0x3 << 0)
#define WM8731_FORMAT_MSB_LEFT_JUSTIFIED (0x0 << 0)
#define WM8731_FORMAT_MSB_RIGHT_JUSTIFIED (0x1 << 0)
#define WM8731_FORMAT_I2S (0x2 << 0)
#define WM8731_FORMAT_DSP (0x3 << 0)
/** Input audio data bit length select*/
#define WM8731_IWL_BITS (0x3 << 2)
#define WM8731_IWL_16_BIT (0x0 << 2)
#define WM8731_IWL_20_BIT (0x1 << 2)
#define WM8731_IWL_24_BIT (0x2 << 2)
#define WM8731_IWL_32_BIT (0x3 << 2)
/** DACLRC phase control*/
#define WM8731_IRP_BITS (0x1 << 4)
/** DAC Left right clock swap*/
#define WM8731_IRSWAP_BIT (0x1 << 5)
/** Master slave mode control*/
#define WM8731_MS_BIT (0x1 << 6)
#define WM8731_ENABLE_MASTER_MODE (0x1 << 6)
#define WM8731_ENABLE_SLAVE_MODE (0x0 << 6)
/** Bit clock invert*/
#define WM8731_BCLKINV_BIT (0x1 << 7)
/** Sampling control*/
#define WM8731_REG_SAMPLECTRL 0x8
/** Mode select, usb mode, normal mode*/
#define WM8731_USBNORMAL_BIT (0x1 << 0)
#define WM8731_NORMAL_MODE (0x1 << 0)
#define WM8731_USB_MODE (0x1 << 1)
/** Base over-sampling rate*/
#define WM8731_BOSR_BIT (0x1 << 1)
#define WM8731_USB_250FS (0x0 << 1)
#define WM8731_USB_272FS (0x1 << 1)
#define WM8731_NORMAL_256FS (0x0 << 1)
#define WM8731_NORMAL_128_192_384_FS (0x1 << 1)
/** Sample rate control*/
#define WM8731_SR_BITS (0xf << 2)
#define WM8731_CLKIDIV2_BIT (0x1 << 6)
#define WM8731_CLKODIV2_BIT (0x1 << 7)
/** Active control register*/
#define WM8731_REG_ACTIVE_CTRL 0x9
/** Activate interface*/
#define WM8731_ACTIVE_BIT (0x1 << 0)
#define WM8731_ACTIVE_INTERFACE_ACTIVE (0x1 << 1)
#define WM8731_ACTIVE_INTERFACE_INACTIVE (0x0 << 1)
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern uint16_t WM8731_Read(Twid *pTwid, uint32_t device, uint32_t regAddr);
extern void WM8731_Write(Twid *pTwid, uint32_t device, uint32_t regAddr, uint16_t data);
extern uint8_t WM8731_DAC_Init(Twid *pTwid, uint32_t device);
extern uint8_t WM8731_VolumeSet(Twid *pTwid, uint32_t device, uint16_t value);
#endif // WM8731_H
+164
View File
@@ -0,0 +1,164 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup adc_module Working with ACC
* The ACC driver provides the interface to configure and use the ACC peripheral.\n
*
* It converts the analog input to digital format. The converted result could be 12bit
* or 10bit. The ACC supports up to 16 analog lines.
*
* To Enable a ACC conversion,the user has to follow these few steps:
* <ul>
* <li> Select an appropriate reference voltage on ADVREF </li>
* <li> Configure the ACC according to its requirements and special needs,which could be
broken down into several parts:
* -# Select the resolution by setting or clearing ACC_MR_LOWRES bit in ACC_MR (Mode Register)
* -# Set ACC clock by setting ACC_MR_PRESCAL bits in ACC_MR, the clock is caculated with
ACCClock = MCK / ( (PRESCAL+1) * 2 )
* -# Set Startup Time,Tracking Clock cycles and Transfer Clock respeticively in ACC_MR.
</li>
* <li> Start conversion by setting ACC_CR_START in ACC_CR. </li>
* </ul>
*
* For more accurate information, please look at the ACC section of the
* Datasheet.
*
* Related files :\n
* \ref adc.c\n
* \ref adc.h\n
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
#include <acc/acc.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initialize the ACC controller
* \param pAcc Pointer to an Acc instance.
* \param idAcc ACC identifier
* \param selplus input connected to inp, 0~7
* \param selminus input connected to inm,0~7
* \param ac_en Analog comprator enabled/disabled,use pattern
* \param edge CF flag triggering mode,use pattern
* \param invert INVert comparator output,use pattern defined in the device header
file
*/
void ACC_Configure(Acc *pAcc,
uint8_t idAcc,
uint8_t selplus,
uint8_t selminus,
uint16_t ac_en,
uint16_t edge,
uint16_t invert)
{
/* Enable peripheral clock*/
PMC->PMC_PCER1 = 1 << (idAcc-32);
/* Reset the controller */
pAcc->ACC_CR |= ACC_CR_SWRST;
/* Write to the MR register */
ACC_CfgModeReg( pAcc,
( selplus & ACC_MR_SELPLUS)
| (( selminus<<4) & ACC_MR_SELMINUS)
| ( ac_en & ACC_MR_ACEN)
| ( edge & ACC_MR_EDGETYP)
| ( invert & ACC_MR_INV) );
//pAcc->ACC_MR |= (ACC_MR_SELFS_OUTPUT|ACC_MR_FE_EN);
pAcc->ACC_ACR = 0x7;
while(pAcc->ACC_ISR & (uint32_t)ACC_ISR_MASK);
}
/**
* Return the Channel Converted Data
* \param pAdc Pointer to an Adc instance.
* \param channel channel to get converted value
* \return Channel converted data of the specified channel
*/
void ACC_SetComparisionPair(Acc *pAcc, uint8_t selplus,uint8_t selminus)
{
uint32_t temp;
ASSERT(selplus < 8 && selminus < 8,"The assigned channel number is invalid!");
temp = pAcc->ACC_MR;
pAcc->ACC_MR = temp & (~ACC_MR_SELMINUS)&(~ACC_MR_SELPLUS);
pAcc->ACC_MR |= ((selplus & ACC_MR_SELPLUS)|((selminus<<4) & ACC_MR_SELMINUS));
}
/**
* Return Comparison Result
* \param pAcc Pointer to an Acc instance.
* \param status value of ACC_ISR
*/
uint8_t ACC_GetComparisionResult(Acc *pAcc,uint32_t status)
{
uint32_t temp = pAcc->ACC_MR;
if( (temp & ACC_MR_INV)== ACC_MR_INV)
{
if( status & ACC_ISR_SCO)
{
return 0; /* inn>inp*/
}
else return 1;/* inp>inn*/
}
else
{
if( status & ACC_ISR_SCO)
{
return 1; /* inp>inn*/
}
else return 0;/* inn>inp*/
}
}
+144
View File
@@ -0,0 +1,144 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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
*
* Interface for configuration the Analog-to-Digital Converter (ACC) peripheral.
*
* !Usage
*
* -# Configurate the pins for ACC
* -# Initialize the ACC with ACC_Initialize().
* -# Select the active channel using ACC_EnableChannel()
* -# Start the conversion with ACC_StartConversion()
* -# Wait the end of the conversion by polling status with ACC_GetStatus()
* -# Finally, get the converted data using ACC_GetConvertedData()
*
*/
#ifndef ACC_H
#define ACC_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <utility/assert.h>
/*------------------------------------------------------------------------------
* Definitions
*------------------------------------------------------------------------------*/
#define ACC_SELPLUS_AD12B0 0
#define ACC_SELPLUS_AD12B1 1
#define ACC_SELPLUS_AD12B2 2
#define ACC_SELPLUS_AD12B3 3
#define ACC_SELPLUS_AD12B4 4
#define ACC_SELPLUS_AD12B5 5
#define ACC_SELPLUS_AD12B6 6
#define ACC_SELPLUS_AD12B7 7
#define ACC_SELMINUS_TS 0
#define ACC_SELMINUS_ADVREF 1
#define ACC_SELMINUS_DAC0 2
#define ACC_SELMINUS_DAC1 3
#define ACC_SELMINUS_AD12B0 4
#define ACC_SELMINUS_AD12B1 5
#define ACC_SELMINUS_AD12B2 6
#define ACC_SELMINUS_AD12B3 7
/*------------------------------------------------------------------------------
* Macros function of register access
*------------------------------------------------------------------------------*/
#define ACC_CfgModeReg(pAcc, mode) { \
(pAcc)->ACC_MR = (mode);\
}
#define ACC_GetModeReg(pAcc) ((pAcc)->ACC_MR)
#define ACC_StartConversion(pAcc) ((pAcc)->ACC_CR = ACC_CR_START)
#define ACC_SoftReset(pAcc) ((pAcc)->ACC_CR = ACC_CR_SWRST)
#define ACC_EnableChannel(pAcc, channel) {\
ASSERT(channel < 16, "ACC Channel not exist");\
(pAcc)->ACC_CHER = (1 << (channel));\
}
#define ACC_DisableChannel (pAcc, channel) {\
ASSERT((channel) < 16, "ACC Channel not exist");\
(pAcc)->ACC_CHDR = (1 << (channel));\
}
#define ACC_EnableIt(pAcc, mode) {\
ASSERT(((mode)&0xFFF00000)== 0, "ACC bad interrupt IER");\
(pAcc)->ACC_IER = (mode);\
}
#define ACC_DisableIt(pAcc, mode) {\
ASSERT(((mode)&0xFFF00000)== 0, "ACC bad interrupt IDR");\
(pAcc)->ACC_IDR = (mode);\
}
#define ACC_EnableDataReadyIt(pAcc) ((pAcc)->ACC_IER = AT91C_ACC_DRDY)
#define ACC_GetStatus(pAcc) ((pAcc)->ACC_ISR)
#define ACC_GetChannelStatus(pAcc) ((pAcc)->ACC_CHSR)
#define ACC_GetInterruptMaskStatus(pAcc) ((pAcc)->ACC_IMR)
#define ACC_GetLastConvertedData(pAcc) ((pAcc)->ACC_LCDR)
#define ACC_CfgAnalogCtrlReg(pAcc,mode) {\
ASSERT(((mode) & 0xFFFCFF3C)==0, "ACC bad analog control config");\
(pAcc)->ACC_ACR = (mode);\
}
#define ACC_CfgExtModeReg(pAcc, extmode) {\
ASSERT(((extmode) & 0xFF00FFFE)==0, "ACC bad extended mode config");\
(pAcc)->ACC_EMR = (extmode);\
}
#define ACC_GetAnalogCtrlReg(pAcc) ((pAcc)->ACC_ACR)
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
void ACC_Configure(Acc *pAcc,
uint8_t idAcc,
uint8_t selplus,
uint8_t selminus,
uint16_t ac_en,
uint16_t edge,
uint16_t invert);
extern uint8_t ACC_GetComparisionResult(Acc *pAcc,uint32_t status);
#endif //#ifndef ACC_H
+231
View File
@@ -0,0 +1,231 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup adc_module Working with ADC
* The ADC driver provides the interface to configure and use the ADC peripheral.
* \n
*
* It converts the analog input to digital format. The converted result could be
* 12bit or 10bit. The ADC supports up to 16 analog lines.
*
* To Enable a ADC conversion,the user has to follow these few steps:
* <ul>
* <li> Select an appropriate reference voltage on ADVREF </li>
* <li> Configure the ADC according to its requirements and special needs,which
* could be broken down into several parts:
* -# Select the resolution by setting or clearing ADC_MR_LOWRES bit in
* ADC_MR (Mode Register)
* -# Set ADC clock by setting ADC_MR_PRESCAL bits in ADC_MR, the clock is
* calculated with ADCClock = MCK / ( (PRESCAL+1) * 2 )
* -# Set Startup Time,Tracking Clock cycles and Transfer Clock respectively
* in ADC_MR.
</li>
* <li> Start conversion by setting ADC_CR_START in ADC_CR. </li>
* </ul>
*
* For more accurate information, please look at the ADC section of the
* Datasheet.
*
* Related files :\n
* \ref adc.c\n
* \ref adc.h\n
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
#include <adc/adc.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initialize the ADC controller
* \param pAdc Pointer to an Adc instance.
* \param trgEn trigger mode, software or Hardware
* \param trgSel hardware trigger selection
* \param sleepMode sleep mode selection
* \param resolution resolution selection 10 bits or 12 bits
* \param mckClock value of MCK in Hz
* \param adcClock value of the ADC clock in Hz
* \param startupTime value of the start up time (in ADCClock) (see datasheet)
* \param trackingt Tracking Time (in ADCClock cycle)
*/
void ADC_Initialize(Adc *pAdc, uint8_t idAdc, uint8_t trgEn, uint8_t trgSel,
uint8_t sleepMode, uint8_t resolution, uint32_t mckClock,
uint32_t adcClock, uint32_t startup, uint32_t tracking) {
uint32_t prescal;
prescal = (mckClock / (2*adcClock)) - 1;
ASSERT( (prescal<0x3F), "ADC Bad PRESCAL\n\r");
TRACE_DEBUG("adcClock:%lu MasterClock:%lu\n\r", (mckClock/((prescal+1)*2)),
mckClock);
if( adcClock != (mckClock/((prescal+1)*2)) ) {
TRACE_WARNING("User and calculated adcClocks are different : "
"user=%lu calc=%lu\n\r",
adcClock, (mckClock/((prescal+1)*2)));
}
/* Enable peripheral clock*/
PMC->PMC_PCER0 = 1 << idAdc;
/* Reset the controller */
ADC_SoftReset(pAdc);
/* Write to the MR register */
ADC_CfgModeReg( pAdc,
( trgEn & ADC_MR_TRGEN)
| ( trgSel & ADC_MR_TRGSEL)
| ( resolution & ADC_MR_LOWRES)
| ( sleepMode & ADC_MR_SLEEP)
| ( (prescal<<8) & ADC_MR_PRESCAL)
| ( (startup<<16) & ADC_MR_STARTUP)
| ( (tracking<<24) & ADC_MR_TRACKTIM) );
}
/**
* Return the Channel Converted Data
* \param pAdc Pointer to an Adc instance.
* \param channel channel to get converted value
*/
uint32_t ADC_GetConvertedData(Adc *pAdc, uint32_t channel) {
uint32_t data=0;
if (15 >= channel) {
data = *((RoReg *)((uint32_t)&(pAdc->ADC_CDR0)+ channel*4));
}
return data;
}
/**
* Set compare channel
* \param pAdc Pointer to an Adc instance.
* \param channel channel number to be set,16 for all channels
*/
void ADC_SetCompareChannel(Adc *pAdc, uint8_t channel) {
ASSERT(channel<=16, "Invalid channel number");
if (channel < 16) {
pAdc->ADC_EMR &= ~(ADC_EMR_CMPALL);
pAdc->ADC_EMR &= ~(ADC_EMR_CMPSEL);
pAdc->ADC_EMR |= (channel << 4);
} else {
pAdc->ADC_EMR |= ADC_EMR_CMPALL;
}
}
/**
* Set compare mode
* \param pAdc Pointer to an Adc instance.
* \param mode compare mode
*/
void ADC_SetCompareMode(Adc *pAdc, uint8_t mode) {
pAdc->ADC_EMR &= ~(ADC_EMR_CMPMODE);
pAdc->ADC_EMR |= mode;
}
/**
* Set comparsion window,one thereshold each time
* \param pAdc Pointer to an Adc instance.
* \param hi_lo Comparison Window
*/
void ADC_SetComparisonWindow(Adc *pAdc, uint32_t hi_lo) {
pAdc->ADC_CWR = hi_lo;
}
/**----------------------------------------------------------------------------
* Test if ADC Interrupt is Masked
* \param pAdc Pointer to an Adc instance.
* \param flag flag to be tested
* \return 1 if interrupt is masked, otherwise 0
*/
uint32_t ADC_IsInterruptMasked(Adc *pAdc, uint32_t flag) {
return (ADC_GetInterruptMaskStatus(pAdc) & flag);
}
/**----------------------------------------------------------------------------
* Test if ADC Status is Set
* \param pAdc Pointer to an Adc instance.
* \param flag flag to be tested
* \return 1 if the staus is set; 0 otherwise
*/
uint32_t ADC_IsStatusSet(Adc *pAdc, uint32_t flag) {
return (ADC_GetStatus(pAdc) & flag);
}
/**----------------------------------------------------------------------------
* Test if ADC channel interrupt Status is Set
* \param adc_sr Value of SR register
* \param channel Channel to be tested
* \return 1 if interrupt status is set, otherwise 0
*/
uint8_t ADC_IsChannelInterruptStatusSet(uint32_t adc_sr, uint32_t channel) {
uint8_t status;
if((adc_sr & (1<<channel)) == (1<<channel)) {
status = 1;
} else {
status = 0;
}
return status;
}
/**
* \brief Read converted data through PDC channel
* \param padc the pointer of adc peripheral
* \param pBuffer the destination buffer
* \param size the size of the buffer
*/
int8_t ADC_ReadBuffer(Adc *pADC, int16_t *pBuffer, int32_t size) {
/* Check if the first PDC bank is free*/
if ((pADC->ADC_RCR == 0) && (pADC->ADC_RNCR == 0)) {
pADC->ADC_RPR = (uint32_t) pBuffer;
pADC->ADC_RCR = size;
pADC->ADC_PTCR = ADC_PTCR_RXTEN;
return 1;
}
/* Check if the second PDC bank is free*/
else if (pADC->ADC_RNCR == 0) {
pADC->ADC_RNPR = (uint32_t) pBuffer;
pADC->ADC_RNCR = size;
return 1;
} else {
return 0;
}
}
+158
View File
@@ -0,0 +1,158 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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
*
* Interface for configuration the Analog-to-Digital Converter (ADC) peripheral.
*
* !Usage
*
* -# Configurate the pins for ADC
* -# Initialize the ADC with ADC_Initialize().
* -# Select the active channel using ADC_EnableChannel()
* -# Start the conversion with ADC_StartConversion()
* -# Wait the end of the conversion by polling status with ADC_GetStatus()
* -# Finally, get the converted data using ADC_GetConvertedData()
*
*/
#ifndef ADC_H
#define ADC_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <utility/assert.h>
/*------------------------------------------------------------------------------
* Definitions
*------------------------------------------------------------------------------*/
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 1
#define ADC_CHANNEL_2 2
#define ADC_CHANNEL_3 3
#define ADC_CHANNEL_4 4
#define ADC_CHANNEL_5 5
#define ADC_CHANNEL_6 6
#define ADC_CHANNEL_7 7
#define ADC_CHANNEL_8 8
#define ADC_CHANNEL_9 9
#define ADC_CHANNEL_10 10
#define ADC_CHANNEL_11 11
#define ADC_CHANNEL_12 12
#define ADC_CHANNEL_13 13
#define ADC_CHANNEL_14 14
#define ADC_CHANNEL_15 15
/*------------------------------------------------------------------------------
* Macros function of register access
*------------------------------------------------------------------------------*/
#define ADC_CfgModeReg(pAdc, mode) { \
ASSERT(((mode)&0xF00000C0)== 0, "ADC Bad configuration ADC MR");\
(pAdc)->ADC_MR = (mode);\
}
#define ADC_GetModeReg(pAdc) ((pAdc)->ADC_MR)
#define ADC_StartConversion(pAdc) ((pAdc)->ADC_CR = ADC_CR_START)
#define ADC_SoftReset(pAdc) ((pAdc)->ADC_CR = ADC_CR_SWRST)
#define ADC_EnableChannel(pAdc, channel) {\
ASSERT(channel < 16, "ADC Channel not exist");\
(pAdc)->ADC_CHER = (1 << (channel));\
}
#define ADC_DisableChannel (pAdc, channel) {\
ASSERT((channel) < 16, "ADC Channel not exist");\
(pAdc)->ADC_CHDR = (1 << (channel));\
}
#define ADC_EnableIt(pAdc, mode) {\
(pAdc)->ADC_IER = (mode);\
}
#define ADC_DisableIt(pAdc, mode) {\
(pAdc)->ADC_IDR = (mode);\
}
#define ADC_EnbaleTS(pAdc,mode) {\
(pAdc)->ADC_ACR |= mode;\
}
#define ADC_EnableDataReadyIt(pAdc) ((pAdc)->ADC_IER = AT91C_ADC_DRDY)
#define ADC_GetStatus(pAdc) ((pAdc)->ADC_ISR)
#define ADC_GetCompareMode(pAdc) (((pAdc)->ADC_EMR)& (ADC_EMR_CMPMODE))
#define ADC_GetChannelStatus(pAdc) ((pAdc)->ADC_CHSR)
#define ADC_GetInterruptMaskStatus(pAdc) ((pAdc)->ADC_IMR)
#define ADC_GetLastConvertedData(pAdc) ((pAdc)->ADC_LCDR)
#define ADC_CfgAnalogCtrlReg(pAdc,mode) {\
ASSERT(((mode) & 0xFFFCFF3C)==0, "ADC bad analog control config");\
(pAdc)->ADC_ACR = (mode);\
}
#define ADC_CfgExtModeReg(pAdc, extmode) {\
ASSERT(((extmode) & 0xFF00FFFE)==0, "ADC bad extended mode config");\
(pAdc)->ADC_EMR = (extmode);\
}
#define ADC_GetAnalogCtrlReg(pAdc) ((pAdc)->ADC_ACR)
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
extern void ADC_Initialize (Adc *pAdc,
uint8_t idAdc,
uint8_t trgEn,
uint8_t trgSel,
uint8_t sleepMode,
uint8_t resolution,
uint32_t mckClock,
uint32_t adcClock,
uint32_t startupTime,
uint32_t sampleAndHoldTime);
extern uint32_t ADC_GetConvertedData(Adc *pAdc, uint32_t channel);
extern void ADC_SetCompareChannel(Adc *pAdc, uint8_t channel);
extern void ADC_SetCompareMode(Adc *pAdc, uint8_t mode);
extern void ADC_SetComparisonWindow(Adc *pAdc, uint32_t hi_lo);
extern uint32_t ADC_IsInterruptMasked(Adc *pAdc, uint32_t flag);
extern uint32_t ADC_IsStatusSet(Adc *pAdc, uint32_t flag);
extern uint8_t ADC_IsChannelInterruptStatusSet(uint32_t adc_sr,
uint32_t channel);
extern int8_t ADC_ReadBuffer(Adc *pADC,int16_t *pBuffer,int32_t size);
#endif //#ifndef ADC_H
@@ -0,0 +1,54 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Provide a routine for asynchronos transfer.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include "async.h"
/*----------------------------------------------------------------------------
* Global functions
*----------------------------------------------------------------------------*/
/**
* \brief Returns 1 if the given transfer has ended; otherwise returns 0.
* \param pAsync Pointer to an Async instance.
*/
uint8_t ASYNC_IsFinished(Async *pAsync)
{
return (pAsync->status != ASYNC_STATUS_PENDING);
}
@@ -0,0 +1,67 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Provide a routine for asynchronos transfer.
*
*/
#ifndef ASYNC_H
#define ASYNC_H
/*----------------------------------------------------------------------------
* Definition
*----------------------------------------------------------------------------*/
/** Transfer is still pending.*/
#define ASYNC_STATUS_PENDING 0xFF
/*----------------------------------------------------------------------------
* Type
*----------------------------------------------------------------------------*/
/** Asynchronous transfer descriptor. */
typedef struct _Async {
/** Asynchronous transfer status.*/
volatile uint8_t status;
/** Callback function to invoke when transfer completes or fails.*/
void *callback;
/** Driver storage area; do not use.*/
uint32_t pStorage[4];
} Async;
/*----------------------------------------------------------------------------
* Global functions
*----------------------------------------------------------------------------*/
extern uint8_t ASYNC_IsFinished(Async *pAsync);
#endif //#ifndef ASYNC_H
+134
View File
@@ -0,0 +1,134 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup crccu_module Working with CRCCU
* The CRCCU driver provides the interface to configure and use the CRCCU
* peripheral.
*
* It performs a CRC computation on a Memory Area. CRC computation is performed
* from the LSB to MSB bit. Three different polynomials are available:
* CCIT802.3, CASTAGNOLI and CCIT16.
*
* To computes CRC of a buffer, the user has to follow these few steps:
* <ul>
* <li>Reset initial CRC by setting RESET bit in CRCCU_CRC_CR,</li>
* <li>Configure CRC descriptor and working mode,</li>
* <li>Start to compute CRC by setting DMAEN in CRCCU_DMA_EN,</li>
* <li>Get CRC value in CRCCU_CRC_SR.</li>
* </ul>
*
* For more accurate information, please look at the CRCCU section of the
* Datasheet.
*
* Related files :\n
* \ref crccu.c\n
* \ref crccu.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Cyclic Redundancy Check Calculation Unit (CRCCU).
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "crccu.h"
#include <utility/assert.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#define CRCCU_TIMEOUT 0xFFFFFFFF
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Reset initial CRC to 0xFFFFFFFF.
*/
void CRCCU_ResetCrcValue(void)
{
Crccu *pCrccu = CRCCU;
pCrccu->CRCCU_CR = CRCCU_CR_RESET;
}
/**
* \brief Configure the CRCCU.
*
* \param dscrAddr CRC decscriptor address.
* \param mode CRC work mode
*/
void CRCCU_Configure(uint32_t dscrAddr, uint32_t mode)
{
Crccu *pCrccu = CRCCU;
pCrccu->CRCCU_DSCR = dscrAddr;
pCrccu->CRCCU_MR = mode;
}
/**
* \brief Start to compute the CRC of a buffer.
*
* \return The CRC of the buffer.
*/
uint32_t CRCCU_ComputeCrc(void)
{
Crccu *pCrccu = CRCCU;
uint32_t timeout = 0;
pCrccu->CRCCU_DMA_EN = CRCCU_DMA_EN_DMAEN;
while (((pCrccu->CRCCU_DMA_SR & CRCCU_DMA_SR_DMASR) == CRCCU_DMA_SR_DMASR)
&& (timeout++ < CRCCU_TIMEOUT));
return (pCrccu->CRCCU_SR);
}
/**
* \brief Compare the CRC of a buffer is match to reference CRC.
*
* \return if 0 CRC is match, else dismatch.
*/
uint32_t CRCCU_CompareCrc(void)
{
Crccu *pCrccu = CRCCU;
if ((pCrccu->CRCCU_ISR & CRCCU_ISR_ERRISR) == CRCCU_ISR_ERRISR) {
return 1;
} else {
return 0;
}
}
@@ -0,0 +1,66 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for Cyclic Redundancy Check Calculation Unit (CRCCU).
*/
#ifndef CRCCU_H
#define CRCCU_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
typedef struct {
unsigned int TR_ADDR;
unsigned int TR_CTRL;
unsigned int reserved[2];
unsigned int TR_CRC;
} CrcDscr;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
void CRCCU_ResetCrcValue(void);
void CRCCU_Configure(uint32_t dscrAddr, uint32_t mode);
uint32_t CRCCU_ComputeCrc(void);
uint32_t CRCCU_CompareCrc(void);
#endif /* #ifndef CRCCU_H */
+172
View File
@@ -0,0 +1,172 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup dacc_module Working with DACC
* The DACC driver provides the interface to configure and use the DACC peripheral.\n
*
* The DACC(Digital-to-Analog Converter Controller) converts digital code to analog output.
* The data to be converted are sent in a common register for all channels. It offers up to 2
* analog outputs.The output voltage ranges from (1/6)ADVREF to (5/6)ADVREF.
*
* To Enable a DACC conversion,the user has to follow these few steps:
* <ul>
* <li> Select an appropriate reference voltage on ADVREF </li>
* <li> Configure the DACC according to its requirements and special needs,which could be
broken down into several parts:
* -# Enable DACC in free running mode by clearing TRGEN in DACC_MR;
* -# Configure Startup Time and Refresh Period through setting STARTUP and REFRESH fields
* in DACC_MR; The refresh mechanism is used to protect the output analog value from
* decreasing.
* -# Enable channels and write digital code to DACC_CDR,in free running mode, the conversion
* is started right after at least one channel is enabled and data is written .
</li>
* </ul>
*
* For more accurate information, please look at the DACC section of the
* Datasheet.
*
* Related files :\n
* \ref DACC.c\n
* \ref DACC.h\n
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
#include <dacc/dacc.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initialize the DACC controller
* \param pDACC Pointer to an DACC instance.
* \param idDACC identifier of DAC peripheral
* \param trgEn trigger mode, free running mode or external Hardware trigger
* \param word transfer size,word or half word
* \param trgSel hardware trigger selection
* \param sleepMode sleep mode selection
* \param mck value of MCK in Hz
* \param refresh refresh period
* \param user_sel user channel selection ,0 or 1
* \param startup value of the start up time (in DACCClock) (see datasheet)
*/
void DACC_Initialize (Dacc *pDACC,
uint8_t idDACC,
uint8_t trgEn,
uint8_t trgSel,
uint8_t word,
uint8_t sleepMode,
uint32_t mck,
uint8_t refresh,/*refresh period*/
uint8_t user_sel,/*user channel selection*/
uint32_t startup
)
{
ASSERT(1024*refresh*1000/(mck/2)<20,"Refresh preriod is too big!");
/* Enable peripheral clock*/
PMC->PMC_PCER0 = 1 << idDACC;
/* Reset the controller */
DACC_SoftReset(pDACC);
/* Write to the MR register */
DACC_CfgModeReg( pDACC,
( trgEn & DACC_MR_TRGEN)
| ( trgSel & DACC_MR_TRGSEL)
| ( word & DACC_MR_WORD)
| ( sleepMode & DACC_MR_SLEEP)
| ( (refresh<<8) & DACC_MR_REFRESH)
| ( (user_sel<<16)& DACC_MR_USER_SEL)
| ( (startup<<24) & DACC_MR_STARTUP));
}
/**
* Set the Conversion Data
* \param pDACC Pointer to an Dacc instance.
* \param channel channel to get converted value
* \return Channel converted data of the specified channel
*/
void DACC_SetConversionData(Dacc *pDACC, uint32_t data)
{
uint32_t mr = pDACC->DACC_MR;
if(mr & DACC_MR_WORD)
{
pDACC->DACC_CDR = data;
}
else
{
pDACC->DACC_CDR = (data&0xFFFF);
}
}
/**
* \brief Write converted data through PDC channel
* \param pDACC the pointer of DACC peripheral
* \param pBuffer the destination buffer
* \param size the size of the buffer
*/
int8_t DACC_WriteBuffer(Dacc *pDACC,int16_t *pBuffer,int32_t size)
{
/* Check if the first PDC bank is free*/
if ((pDACC->DACC_TCR == 0) && (pDACC->DACC_TNCR == 0)) {
pDACC->DACC_TPR = (uint32_t) pBuffer;
pDACC->DACC_TCR = size;
pDACC->DACC_PTCR = DACC_PTCR_RXTEN;
return 1;
}
/* Check if the second PDC bank is free*/
else if (pDACC->DACC_TNCR == 0) {
pDACC->DACC_TNPR = (uint32_t) pBuffer;
pDACC->DACC_TNCR = size;
return 1;
}
else {
return 0;
}
}
+133
View File
@@ -0,0 +1,133 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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
*
* Interface for configuration the Analog-to-Digital Converter (DACC) peripheral.
*
* !Usage
*
* -# Configurate the pins for DACC
* -# Initialize the DACC with DACC_Initialize().
* -# Select the active channel using DACC_EnableChannel()
* -# Start the conversion with DACC_StartConversion()
* -# Wait the end of the conversion by polling status with DACC_GetStatus()
* -# Finally, get the converted data using DACC_GetConvertedData()
*
*/
#ifndef DACC_H
#define DACC_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <utility/assert.h>
/*------------------------------------------------------------------------------
* Definitions
*------------------------------------------------------------------------------*/
#define DACC_CHANNEL_0 0
#define DACC_CHANNEL_1 1
/*------------------------------------------------------------------------------
* Macros function of register access
*------------------------------------------------------------------------------*/
#define DACC_CfgModeReg(pDACC, mode) { \
(pDACC)->DACC_MR = (mode);\
}
#define DACC_GetModeReg(pDACC) ((pDACC)->DACC_MR)
#define DACC_StartConversion(pDACC) ((pDACC)->DACC_CR = DACC_CR_START)
#define DACC_SoftReset(pDACC) ((pDACC)->DACC_CR = DACC_CR_SWRST)
#define DACC_EnableChannel(pDACC, channel) {\
(pDACC)->DACC_CHER = (1 << (channel));\
}
#define DACC_DisableChannel (pDACC, channel) {\
(pDACC)->DACC_CHDR = (1 << (channel));\
}
#define DACC_EnableIt(pDACC, mode) {\
ASSERT(((mode)&0xFFF00000)== 0, "DACC bad interrupt IER");\
(pDACC)->DACC_IER = (mode);\
}
#define DACC_DisableIt(pDACC, mode) {\
ASSERT(((mode)&0xFFF00000)== 0, "DACC bad interrupt IDR");\
(pDACC)->DACC_IDR = (mode);\
}
#define DACC_EnableDataReadyIt(pDACC) ((pDACC)->DACC_IER = AT91C_DACC_DRDY)
#define DACC_GetStatus(pDACC) ((pDACC)->DACC_ISR)
#define DACC_GetChannelStatus(pDACC) ((pDACC)->DACC_CHSR)
#define DACC_GetInterruptMaskStatus(pDACC) ((pDACC)->DACC_IMR)
#define DACC_GetLastConvertedData(pDACC) ((pDACC)->DACC_LCDR)
#define DACC_CfgAnalogCtrlReg(pDACC,mode) {\
ASSERT(((mode) & 0xFFFCFF3C)==0, "DACC bad analog control config");\
(pDACC)->DACC_ACR = (mode);\
}
#define DACC_CfgExtModeReg(pDACC, extmode) {\
ASSERT(((extmode) & 0xFF00FFFE)==0, "DACC bad extended mode config");\
(pDACC)->DACC_EMR = (extmode);\
}
#define DACC_GetAnalogCtrlReg(pDACC) ((pDACC)->DACC_ACR)
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
extern void DACC_Initialize (Dacc *pDACC,
uint8_t idDACC,
uint8_t trgEn,
uint8_t trgSel,
uint8_t word,
uint8_t sleepMode,
uint32_t mck,
uint8_t refresh,/*refresh period*/
uint8_t user_sel,/*user channel selection*/
uint32_t startup
);
extern void DACC_SetConversionData(Dacc *pDACC, uint32_t data);
#endif //#ifndef DACC_H
+286
View File
@@ -0,0 +1,286 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup efc_module Working with Enhanced Embedded Flash
* The EEFC driver provides the interface to configure and use the EEFC
* peripheral.
*
* The user needs to set the number of wait states depending on the frequency used.\n
* Configure number of cycles for flash read/write operations in the FWS field of EEFC_FMR.
*
* It offers a function to send flash command to EEFC and waits for the
* flash to be ready.
*
* To send flash command, the user could do in either of following way:
* <ul>
* <li>Write a correct key, command and argument in EEFC_FCR. </li>
* <li>Or, Use IAP (In Application Programming) function which is executed from
* ROM directly, this allows flash programming to be done by code running in flash.</li>
* <li>Once the command is achieved, it can be detected even by polling EEFC_FSR or interrupt.
* </ul>
*
* The command argument could be a page number,GPNVM number or nothing, it depends on
* the command itself. Some useful functions in this driver could help user tranlate physical
* flash address into a page number and vice verse.
*
* For more accurate information, please look at the EEFC section of the
* Datasheet.
*
* Related files :\n
* \ref efc.c\n
* \ref efc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Emhance embedded Flash (EEFC) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include "efc.h"
#include <utility/assert.h>
#include <utility/trace.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Enables the flash ready interrupt source on the EEFC peripheral.
*
* \param efc Pointer to a Efc instance
*/
void EFC_EnableFrdyIt(Efc *efc)
{
efc->EEFC_FMR |= EEFC_FMR_FRDY;
}
/**
* \brief Disables the flash ready interrupt source on the EEFC peripheral.
*
* \param efc Pointer to a Efc instance
*/
void EFC_DisableFrdyIt(Efc *efc)
{
efc->EEFC_FMR &= ~EEFC_FMR_FRDY;
}
/**
* \brief Set read/write wait state on the EEFC perpherial.
*
* \param efc Pointer to a Efc instance
* \param cycles the number of wait states in cycle.
*/
void EFC_SetWaitState(Efc *efc, uint8_t cycles)
{
uint32_t value;
value = efc->EEFC_FMR;
value &= ~EEFC_FMR_FWS;
value |= cycles << 8;
efc->EEFC_FMR = value;
}
/**
* \brief Returns the current status of the EEFC.
*
* \note Keep in mind that this function clears the value of some status bits (LOCKE, PROGE).
*
* \param efc Pointer to a Efc instance
*/
uint32_t EFC_GetStatus(Efc *efc)
{
return efc->EEFC_FSR;
}
/**
* \brief Returns the result of the last executed command.
*
* \param efc Pointer to a Efc instance
*/
uint32_t EFC_GetResult(Efc *efc) {
return efc->EEFC_FRR;
}
/**
* \brief Translates the given address page and offset values.
* \note The resulting values are stored in the provided variables if they are not null.
*
* \param efc Pointer to a Efc instance
* \param address Address to translate.
* \param pPage First page accessed.
* \param pOffset Byte offset in first page.
*/
void EFC_TranslateAddress(
Efc **efc,
uint32_t address,
unsigned short *pPage,
unsigned short *pOffset)
{
Efc *pEfc;
unsigned short page;
unsigned short offset;
SANITY_CHECK(address >= AT91C_IFLASH);
SANITY_CHECK(address <= (AT91C_IFLASH + AT91C_IFLASH_SIZE));
pEfc = EFC;
page = (address - AT91C_IFLASH) / AT91C_IFLASH_PAGE_SIZE;
offset = (address - AT91C_IFLASH) % AT91C_IFLASH_PAGE_SIZE;
TRACE_DEBUG("Translated 0x%08X to page=%d and offset=%d\n\r", address, page, offset);
// Store values
if (pEfc) {
*efc = pEfc;
}
if (pPage) {
*pPage = page;
}
if (pOffset) {
*pOffset = offset;
}
}
/**
* \brief Computes the address of a flash access given the page and offset.
*
* \param efc Pointer to a Efc instance
* \param page Page number.
* \param offset Byte offset inside page.
* \param pAddress Computed address (optional).
*/
void EFC_ComputeAddress(
Efc *efc,
unsigned short page,
unsigned short offset,
uint32_t *pAddress)
{
uint32_t address;
SANITY_CHECK(efc);
SANITY_CHECK(page <= AT91C_IFLASH_NB_OF_PAGES);
SANITY_CHECK(offset < AT91C_IFLASH_PAGE_SIZE);
// Compute address
address = AT91C_IFLASH + page * AT91C_IFLASH_PAGE_SIZE + offset;
// Store result
if (pAddress) {
*pAddress = address;
}
}
/**
* \brief Starts the executing the given command on the EEFC and returns as soon as the command is started.
*
* \note It does NOT set the FMCN field automatically.
* \param efc Pointer to a Efc instance
* \param command Command to execute.
* \param argument Command argument (should be 0 if not used).
*/
void EFC_StartCommand(Efc *efc, uint8_t command, unsigned short argument)
{
// Check command & argument
switch (command) {
case EFC_FCMD_WP:
case EFC_FCMD_WPL:
case EFC_FCMD_EWP:
case EFC_FCMD_EWPL:
case EFC_FCMD_SLB:
case EFC_FCMD_CLB:
ASSERT(argument < AT91C_IFLASH_NB_OF_PAGES,
"-F- Embedded flash has only %d pages\n\r",
AT91C_IFLASH_NB_OF_PAGES);
break;
case EFC_FCMD_SFB:
case EFC_FCMD_CFB:
ASSERT(argument < 2, "-F- Embedded flash has only %d GPNVMs\n\r", 2);
break;
case EFC_FCMD_GETD:
case EFC_FCMD_EA:
case EFC_FCMD_GLB:
case EFC_FCMD_GFB:
case EFC_FCMD_STUI:
ASSERT(argument == 0, "-F- Argument is meaningless for the given command.\n\r");
break;
default: ASSERT(0, "-F- Unknown command %d\n\r", command);
}
// Start command Embedded flash
ASSERT((efc->EEFC_FSR & EEFC_FMR_FRDY) == EEFC_FMR_FRDY, "-F- EEFC is not ready\n\r");
efc->EEFC_FCR = (0x5A << 24) | (argument << 8) | command;
}
/**
* \brief Performs the given command and wait until its completion (or an error).
*
* \param efc Pointer to a Efc instance
* \param command Command to perform.
* \param argument Optional command argument.
* \return 0 if successful, otherwise returns an error code.
*/
uint8_t EFC_PerformCommand(Efc *efc, uint8_t command, unsigned short argument)
{
#if defined(flash) || defined(USE_IAP_FEATURE)
// Pointer on IAP function in ROM
static uint32_t (*IAP_PerformCommand)(uint32_t, uint32_t);
IAP_PerformCommand = (uint32_t (*)(uint32_t, uint32_t)) *((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
IAP_PerformCommand(0, (0x5A << 24) | (argument << 8) | command);
return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));
#else
uint32_t status;
efc->EEFC_FCR = (0x5A << 24) | (argument << 8) | command;
do {
status = efc->EEFC_FSR;
}
while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (status & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));
#endif
}
+112
View File
@@ -0,0 +1,112 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* \par Purpose
*
* Interface for configuration the Enhanced Embedded Flash Controller (EEFC) peripheral.
*
* \par Usage
*
* -# Enable/disable %flash ready interrupt sources using EFC_EnableFrdyIt()
* and EFC_DisableFrdyIt().
* -# Translates the given address into which EEFC, page and offset values
* for difference density %flash memory using EFC_TranslateAddress().
* -# Computes the address of a %flash access given the EFC, page and offset
* for difference density %flash memory using EFC_ComputeAddress().
* -# Start the executing command with EFC_StartCommand()
* -# Retrieve the current status of the EFC using EFC_GetStatus().
* -# Retrieve the result of the last executed command with EFC_GetResult().
*/
#ifndef EFC_H
#define EFC_H
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/* EFC command */
#define EFC_FCMD_GETD 0x00
#define EFC_FCMD_WP 0x01
#define EFC_FCMD_WPL 0x02
#define EFC_FCMD_EWP 0x03
#define EFC_FCMD_EWPL 0x04
#define EFC_FCMD_EA 0x05
#define EFC_FCMD_SLB 0x08
#define EFC_FCMD_CLB 0x09
#define EFC_FCMD_GLB 0x0A
#define EFC_FCMD_SFB 0x0B
#define EFC_FCMD_CFB 0x0C
#define EFC_FCMD_GFB 0x0D
#define EFC_FCMD_STUI 0x0E
#define EFC_FCMD_SPUI 0x0F
/* The IAP function entry addreass */
#define CHIP_FLASH_IAP_ADDRESS (0x00800008)
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void EFC_EnableFrdyIt(Efc *efc);
extern void EFC_DisableFrdyIt(Efc *efc);
extern void EFC_SetWaitState(Efc *efc, uint8_t cycles);
extern void EFC_TranslateAddress(
Efc **pEfc,
uint32_t address,
unsigned short *pPage,
unsigned short *pOffset);
extern void EFC_ComputeAddress(
Efc *efc,
unsigned short page,
unsigned short offset,
uint32_t *pAddress);
extern void EFC_StartCommand(
Efc *efc,
uint8_t command,
unsigned short argument);
extern uint8_t EFC_PerformCommand(
Efc *efc,
uint8_t command,
unsigned short argument);
extern uint32_t EFC_GetStatus(Efc *efc);
extern uint32_t EFC_GetResult(Efc *efc);
#endif //#ifndef EFC_H
@@ -0,0 +1,494 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup flashd_module Flash Memory Interface
* The flash driver manages the programming, erasing, locking and unlocking sequences
* with dedicated commands.
*
* To implement flash programing operation, the user has to follow these few steps :
* <ul>
* <li>Configue flash wait states to initializes the flash. </li>
* <li>Checks whether a region to be programmed is locked. </li>
* <li>Unlocks the user region to be programmed if the region have locked before.</li>
* <li>Erases the user page before program (optional).</li>
* <li>Writes the user page from the page buffer.</li>
* <li>Locks the region of programmed area if any.</li>
* </ul>
*
* Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable data corruption.
* A check of this validity and padding for 32-bit alignment should be done in write algorithm.
* Lock/unlock range associated with the user address range is automatically translated.
*
* This security bit can be enabled through the command "Set General Purpose NVM Bit 0".
*
* A 128-bit factory programmed unique ID could be read to serve several purposes.
*
* The driver accesses the flash memory by calling the lowlevel module provided in \ref efc_module.
* For more accurate information, please look at the EEFC section of the Datasheet.
*
* Related files :\n
* \ref flashd.c\n
* \ref flashd.h.\n
* \ref efc.c\n
* \ref efc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* The flash driver provides the unified interface for flash program operations.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "flashd.h"
#include <board.h>
#include <efc/efc.h>
#include <utility/math.h>
#include <utility/assert.h>
#include <utility/trace.h>
#include <string.h>
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Computes the lock range associated with the given address range.
*
* \param start Start address of lock range.
* \param end End address of lock range.
* \param pActualStart Actual start address of lock range.
* \param pActualEnd Actual end address of lock range.
*/
static void ComputeLockRange(
uint32_t start,
uint32_t end,
uint32_t *pActualStart,
uint32_t *pActualEnd)
{
Efc *pStartEfc, *pEndEfc;
uint16_t startPage, endPage;
uint16_t numPagesInRegion;
uint16_t actualStartPage, actualEndPage;
// Convert start and end address in page numbers
EFC_TranslateAddress(&pStartEfc, start, &startPage, 0);
EFC_TranslateAddress(&pEndEfc, end, &endPage, 0);
// Find out the first page of the first region to lock
numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
actualStartPage = startPage - (startPage % numPagesInRegion);
actualEndPage = endPage;
if ((endPage % numPagesInRegion) != 0) {
actualEndPage += numPagesInRegion - (endPage % numPagesInRegion);
}
// Store actual page numbers
EFC_ComputeAddress(pStartEfc, actualStartPage, 0, pActualStart);
EFC_ComputeAddress(pEndEfc, actualEndPage, 0, pActualEnd);
TRACE_DEBUG("Actual lock range is 0x%06X - 0x%06X\n\r", *pActualStart, *pActualEnd);
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initializes the flash driver.
*
* \param mck Master clock frequency in Hz.
*/
void FLASHD_Initialize(uint32_t mck)
{
EFC_DisableFrdyIt(EFC);
if ((mck/1000000) >= 64) {
EFC_SetWaitState(EFC, 2);
}
else if ((mck/1000000) >= 50) {
EFC_SetWaitState(EFC, 1);
}
else {
EFC_SetWaitState(EFC, 0);
}
}
/**
* \brief Erases the entire flash.
*
* \param address Flash start address.
* \return 0 if successful; otherwise returns an error code.
*/
uint8_t FLASHD_Erase(uint32_t address)
{
Efc *pEfc;
uint16_t page;
uint16_t offset;
uint8_t error;
SANITY_CHECK((address >=AT91C_IFLASH) || (address <= (AT91C_IFLASH + AT91C_IFLASH_SIZE)));
// Translate write address
EFC_TranslateAddress(&pEfc, address, &page, &offset);
error = EFC_PerformCommand(pEfc, EFC_FCMD_EA, 0);
return error;
}
static uint8_t pPageBuffer[AT91C_IFLASH_PAGE_SIZE];
/**
* \brief Writes a data buffer in the internal flash
*
* \note This function works in polling mode, and thus only returns when the
* data has been effectively written.
* \param address Write address.
* \param pBuffer Data buffer.
* \param size Size of data buffer in bytes.
* \return 0 if successful, otherwise returns an error code.
*/
uint8_t FLASHD_Write(
uint32_t address,
const void *pBuffer,
uint32_t size)
{
Efc *pEfc;
uint16_t page;
uint16_t offset;
uint32_t writeSize;
uint32_t pageAddress;
uint16_t padding;
uint8_t error;
uint32_t sizeTmp;
uint32_t *pAlignedDestination;
uint32_t *pAlignedSource;
SANITY_CHECK(pBuffer);
SANITY_CHECK(address >=AT91C_IFLASH);
SANITY_CHECK((address + size) <= (AT91C_IFLASH + AT91C_IFLASH_SIZE));
// Translate write address
EFC_TranslateAddress(&pEfc, address, &page, &offset);
// Write all pages
while (size > 0) {
// Copy data in temporary buffer to avoid alignment problems
writeSize = min(AT91C_IFLASH_PAGE_SIZE - offset, size);
EFC_ComputeAddress(pEfc, page, 0, &pageAddress);
padding = AT91C_IFLASH_PAGE_SIZE - offset - writeSize;
// Pre-buffer data
memcpy(pPageBuffer, (void *) pageAddress, offset);
// Buffer data
memcpy(pPageBuffer + offset, pBuffer, writeSize);
// Post-buffer data
memcpy(pPageBuffer + offset + writeSize, (void *) (pageAddress + offset + writeSize), padding);
// Write page
// Writing 8-bit and 16-bit data is not allowed
// and may lead to unpredictable data corruption
pAlignedDestination = (uint32_t*)pageAddress;
pAlignedSource = (uint32_t*)pPageBuffer;
sizeTmp = AT91C_IFLASH_PAGE_SIZE;
while (sizeTmp >= 4) {
*pAlignedDestination++ = *pAlignedSource++;
sizeTmp -= 4;
}
// Send writing command
error = EFC_PerformCommand(pEfc, EFC_FCMD_EWP, page);
if (error) {
return error;
}
// Progression
address += AT91C_IFLASH_PAGE_SIZE;
pBuffer = (void *) ((uint32_t) pBuffer + writeSize);
size -= writeSize;
page++;
offset = 0;
}
return 0;
}
/**
* \brief Locks all the regions in the given address range. The actual lock range is
* reported through two output parameters.
* \param address Start address of lock range.
* \param end End address of lock range.
* \param pActualStart Start address of the actual lock range (optional).
* \param pActualEnd End address of the actual lock range (optional).
* \return 0 if successful, otherwise returns an error code.
*/
uint8_t FLASHD_Lock(
uint32_t start,
uint32_t end,
uint32_t *pActualStart,
uint32_t *pActualEnd)
{
Efc *pEfc;
uint32_t actualStart, actualEnd;
uint16_t startPage, endPage;
uint8_t error;
uint16_t numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
// Compute actual lock range and store it
ComputeLockRange(start, end, &actualStart, &actualEnd);
if (pActualStart) {
*pActualStart = actualStart;
}
if (pActualEnd) {
*pActualEnd = actualEnd;
}
// Compute page numbers
EFC_TranslateAddress(&pEfc, actualStart, &startPage, 0);
EFC_TranslateAddress(0, actualEnd, &endPage, 0);
// Lock all pages
while (startPage < endPage) {
error = EFC_PerformCommand(pEfc, EFC_FCMD_SLB, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
return 0;
}
/**
* \brief Unlocks all the regions in the given address range. The actual unlock range is
* reported through two output parameters.
* \param address Start address of unlock range.
* \param end End address of unlock range.
* \param pActualStart Start address of the actual unlock range (optional).
* \param pActualEnd End address of the actual unlock range (optional).
* \return 0 if successful, otherwise returns an error code.
*/
uint8_t FLASHD_Unlock(
uint32_t start,
uint32_t end,
uint32_t *pActualStart,
uint32_t *pActualEnd)
{
Efc *pEfc;
uint32_t actualStart, actualEnd;
uint16_t startPage, endPage;
uint8_t error;
uint16_t numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
// Compute actual unlock range and store it
ComputeLockRange(start, end, &actualStart, &actualEnd);
if (pActualStart) {
*pActualStart = actualStart;
}
if (pActualEnd) {
*pActualEnd = actualEnd;
}
// Compute page numbers
EFC_TranslateAddress(&pEfc, actualStart, &startPage, 0);
EFC_TranslateAddress(0, actualEnd, &endPage, 0);
// Unlock all pages
while (startPage < endPage) {
error = EFC_PerformCommand(pEfc, EFC_FCMD_CLB, startPage);
if (error) {
return error;
}
startPage += numPagesInRegion;
}
return 0;
}
/**
* \brief Returns the number of locked regions inside the given address range.
*
* \param address Start address of range
* \param end End address of range.
*/
uint8_t FLASHD_IsLocked(uint32_t start, uint32_t end)
{
Efc *pEfc;
uint16_t startPage, endPage;
uint8_t startRegion, endRegion;
uint32_t numPagesInRegion;
uint32_t status;
uint8_t error;
uint32_t numLockedRegions = 0;
SANITY_CHECK(end >= start);
SANITY_CHECK((start >=AT91C_IFLASH) && (end <= AT91C_IFLASH + AT91C_IFLASH_SIZE));
// Compute page numbers
EFC_TranslateAddress(&pEfc, start, &startPage, 0);
EFC_TranslateAddress(0, end, &endPage, 0);
// Compute region numbers
numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE;
startRegion = startPage / numPagesInRegion;
endRegion = endPage / numPagesInRegion;
if ((endPage % numPagesInRegion) != 0) {
endRegion++;
}
// Retrieve lock status
error = EFC_PerformCommand(pEfc, EFC_FCMD_GLB, 0);
ASSERT(!error, "-F- Error while trying to fetch lock bits status (0x%02X)\n\r", error);
status = EFC_GetResult(pEfc);
// Check status of each involved region
while (startRegion < endRegion) {
if ((status & (1 << startRegion)) != 0) {
numLockedRegions++;
}
startRegion++;
}
return numLockedRegions;
}
/**
* \brief Check if the given GPNVM bit is set or not.
*
* \param gpnvm GPNVM bit index.
* \returns 1 if the given GPNVM bit is currently set; otherwise returns 0.
*/
uint8_t FLASHD_IsGPNVMSet(uint8_t gpnvm)
{
uint8_t error;
uint32_t status;
SANITY_CHECK(gpnvm < 2);
// Get GPNVMs status
error = EFC_PerformCommand(EFC, EFC_FCMD_GFB, 0);
ASSERT(!error, "-F- Error while trying to fetch GPNVMs status (0x%02X)\n\r", error);
status = EFC_GetResult(EFC);
// Check if GPNVM is set
if ((status & (1 << gpnvm)) != 0) {
return 1;
}
else {
return 0;
}
}
/**
* \brief Sets the selected GPNVM bit.
*
* \param gpnvm GPNVM bit index.
* \returns 0 if successful; otherwise returns an error code.
*/
uint8_t FLASHD_SetGPNVM(uint8_t gpnvm)
{
SANITY_CHECK(gpnvm < 2);
if (!FLASHD_IsGPNVMSet(gpnvm)) {
return EFC_PerformCommand(EFC, EFC_FCMD_SFB, gpnvm);
}
else {
return 0;
}
}
/**
* \brief Clears the selected GPNVM bit.
*
* \param gpnvm GPNVM bit index.
* \returns 0 if successful; otherwise returns an error code.
*/
uint8_t FLASHD_ClearGPNVM(uint8_t gpnvm)
{
SANITY_CHECK(gpnvm < 2);
if (FLASHD_IsGPNVMSet(gpnvm)) {
return EFC_PerformCommand(EFC, EFC_FCMD_CFB, gpnvm);
}
else {
return 0;
}
}
/**
* \brief Read the unique ID.
*
* \param uniqueID pointer on a 4bytes char containing the unique ID value.
* \returns 0 if successful; otherwise returns an error code.
*/
uint8_t FLASHD_ReadUniqueID (uint32_t * uniqueID)
{
uint8_t error;
SANITY_CHECK(uniqueID != NULL);
uniqueID[0] = 0;
uniqueID[1] = 0;
uniqueID[2] = 0;
uniqueID[3] = 0;
EFC_StartCommand(EFC, EFC_FCMD_STUI, 0);
uniqueID[0] = *(uint32_t *)AT91C_IFLASH;
uniqueID[1] = *(uint32_t *)(AT91C_IFLASH + 4);
uniqueID[2] = *(uint32_t *)(AT91C_IFLASH + 8);
uniqueID[3] = *(uint32_t *)(AT91C_IFLASH + 12);
error = EFC_PerformCommand(EFC, EFC_FCMD_SPUI, 0);
if (error) return error;
return 0;
}
@@ -0,0 +1,84 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* The flash driver provides the unified interface for flash program operations.
*
*/
#ifndef FLASHD_H
#define FLASHD_H
#include <board.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void FLASHD_Initialize(uint32_t mck);
extern uint8_t FLASHD_Erase(uint32_t address);
extern uint8_t FLASHD_Write(
uint32_t address,
const void *pBuffer,
uint32_t size);
extern uint8_t FLASHD_Lock(
uint32_t start,
uint32_t end,
uint32_t *pActualStart,
uint32_t *pActualEnd);
extern uint8_t FLASHD_Unlock(
uint32_t start,
uint32_t end,
uint32_t *pActualStart,
uint32_t *pActualEnd);
extern uint8_t FLASHD_IsLocked(
uint32_t start,
uint32_t end);
extern uint8_t FLASHD_SetGPNVM(uint8_t gpnvm);
extern uint8_t FLASHD_ClearGPNVM(uint8_t gpnvm);
extern uint8_t FLASHD_IsGPNVMSet(uint8_t gpnvm);
#define FLASHD_IsSecurityBitSet() FLASHD_IsGPNVMSet(0)
#define FLASHD_SetSecurityBit() FLASHD_SetGPNVM(0)
extern uint8_t FLASHD_ReadUniqueID(uint32_t * uniqueID);
#endif //#ifndef FLASHD_H
+85
View File
@@ -0,0 +1,85 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
#ifndef COLOR_H
#define COLOR_H
/**
* \file
*
* RGB 24-bits color table definition.
*
*/
/*
* RGB 24 Bpp
* RGB 888
* R7R6R5R4 R3R2R1R0 G7G6G5G4 G3G2G1G0 B7B6B5B4 B3B2B1B0
*/
#define COLOR_BLACK 0x000000
#define COLOR_WHITE 0xFFFFFF
#define COLOR_BLUE 0x0000FF
#define COLOR_GREEN 0x00FF00
#define COLOR_RED 0xFF0000
#define COLOR_NAVY 0x000080
#define COLOR_DARKBLUE 0x00008B
#define COLOR_DARKGREEN 0x006400
#define COLOR_DARKCYAN 0x008B8B
#define COLOR_CYAN 0x00FFFF
#define COLOR_TURQUOISE 0x40E0D0
#define COLOR_INDIGO 0x4B0082
#define COLOR_DARKRED 0x800000
#define COLOR_OLIVE 0x808000
#define COLOR_GRAY 0x808080
#define COLOR_SKYBLUE 0x87CEEB
#define COLOR_BLUEVIOLET 0x8A2BE2
#define COLOR_LIGHTGREEN 0x90EE90
#define COLOR_DARKVIOLET 0x9400D3
#define COLOR_YELLOWGREEN 0x9ACD32
#define COLOR_BROWN 0xA52A2A
#define COLOR_DARKGRAY 0xA9A9A9
#define COLOR_SIENNA 0xA0522D
#define COLOR_LIGHTBLUE 0xADD8E6
#define COLOR_GREENYELLOW 0xADFF2F
#define COLOR_SILVER 0xC0C0C0
#define COLOR_LIGHTGREY 0xD3D3D3
#define COLOR_LIGHTCYAN 0xE0FFFF
#define COLOR_VIOLET 0xEE82EE
#define COLOR_AZUR 0xF0FFFF
#define COLOR_BEIGE 0xF5F5DC
#define COLOR_MAGENTA 0xFF00FF
#define COLOR_TOMATO 0xFF6347
#define COLOR_GOLD 0xFFD700
#define COLOR_ORANGE 0xFFA500
#define COLOR_SNOW 0xFFFAFA
#define COLOR_YELLOW 0xFFFF00
#endif /* #define COLOR_H */
+333
View File
@@ -0,0 +1,333 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of draw function on LCD, Include draw text, image
* and basic shapes (line, rectangle, circle).
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <string.h>
#include "draw.h"
#include "font.h"
#include <board.h>
#include <utility/assert.h>
#include <ili9325/ili9325.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Fills the given LCD buffer with a particular color.
*
* \param color Fill color.
*/
void LCDD_Fill(uint32_t color)
{
uint32_t i;
LCD_SetCursor(0, 0);
LCD_WriteRAM_Prepare();
for (i = 0; i < (BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT); i++) {
LCD_WriteRAM(color);
}
}
/**
* \brief Draw a pixel on LCD of given color.
*
* \param x X-coordinate of pixel.
* \param y Y-coordinate of pixel.
* \param color Pixel color.
*/
void LCDD_DrawPixel(
uint32_t x,
uint32_t y,
uint32_t color)
{
LCD_SetCursor(x, y);
LCD_WriteRAM_Prepare();
LCD_WriteRAM(color);
}
/**
* \brief Read a pixel from LCD.
*
* \param x X-coordinate of pixel.
* \param y Y-coordinate of pixel.
*
* \return color Readed pixel color.
*/
uint32_t LCDD_ReadPixel(
uint32_t x,
uint32_t y)
{
uint32_t color;
LCD_SetCursor(x, y);
LCD_ReadRAM_Prepare();
color = LCD_ReadRAM();
return color;
}
/*
* \brief Draw a line on LCD, horizontal and vertical line are supported.
*
* \param x X-coordinate of line start.
* \param y Y-coordinate of line start.
* \param length line length.
* \param direction line direction: 0 - horizontal, 1 - vertical.
* \param color Pixel color.
*/
void LCDD_DrawLine(
uint32_t x,
uint32_t y,
uint32_t length,
uint32_t direction,
uint32_t color)
{
uint32_t i = 0;
LCD_SetCursor(x, y);
if(direction == DIRECTION_HLINE) {
LCD_WriteRAM_Prepare();
for(i = 0; i < length; i++) {
LCD_WriteRAM(color);
}
}
else {
for(i = 0; i < length; i++) {
LCD_WriteRAM_Prepare();
LCD_WriteRAM(color);
y++;
LCD_SetCursor(x, y);
}
}
}
/*
* \brief Draws a rectangle on LCD, at the given coordinates.
*
* \param x X-coordinate of upper-left rectangle corner.
* \param y Y-coordinate of upper-left rectangle corner.
* \param width Rectangle width in pixels.
* \param height Rectangle height in pixels.
* \param color Rectangle color.
*/
void LCDD_DrawRectangle(
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height,
uint32_t color)
{
LCDD_DrawLine(x, y, width, DIRECTION_HLINE, color);
LCDD_DrawLine(x, (y + height), width, DIRECTION_HLINE, color);
LCDD_DrawLine(x, y, height, DIRECTION_VLINE, color);
LCDD_DrawLine((x + width), y, height, DIRECTION_VLINE, color);
}
/*
* \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
*
* \param x X-coordinate of upper-left rectangle corner.
* \param y Y-coordinate of upper-left rectangle corner.
* \param width Rectangle width in pixels.
* \param height Rectangle height in pixels.
* \param color Rectangle color.
*/
void LCDD_DrawRectangleWithFill(
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height,
uint32_t color)
{
uint32_t i;
for (i = 0; i < height; i++) {
LCDD_DrawLine(x, y+i, width, DIRECTION_HLINE, color);
}
}
/**
* \brief Draws a circle on LCD, at the given coordinates.
*
* \param x X-coordinate of circle center.
* \param y Y-coordinate of circle center.
* \param r circle radius.
* \param color circle color.
*/
void LCDD_DrawCircle(
uint32_t x,
uint32_t y,
uint32_t r,
uint32_t color)
{
signed int d; /* Decision Variable */
uint32_t curX; /* Current X Value */
uint32_t curY; /* Current Y Value */
d = 3 - (r << 1);
curX = 0;
curY = r;
while (curX <= curY)
{
LCDD_DrawPixel(x + curX, y + curY, color);
LCDD_DrawPixel(x + curX, y - curY, color);
LCDD_DrawPixel(x - curX, y + curY, color);
LCDD_DrawPixel(x - curX, y - curY, color);
LCDD_DrawPixel(x + curY, y + curX, color);
LCDD_DrawPixel(x + curY, y - curX, color);
LCDD_DrawPixel(x - curY, y + curX, color);
LCDD_DrawPixel(x - curY, y - curX, color);
if (d < 0) {
d += (curX << 2) + 6;
}
else {
d += ((curX - curY) << 2) + 10;
curY--;
}
curX++;
}
}
/**
* \brief Draws a string inside a LCD buffer, at the given coordinates. Line breaks
* will be honored.
*
* \param x X-coordinate of string top-left corner.
* \param y Y-coordinate of string top-left corner.
* \param pString String to display.
* \param color String color.
*/
void LCDD_DrawString(
uint32_t x,
uint32_t y,
const uint8_t *pString,
uint32_t color)
{
unsigned xorg = x;
while (*pString != 0) {
if (*pString == '\n') {
y += gFont.height + 2;
x = xorg;
}
else {
LCDD_DrawChar(x, y, *pString, color);
x += gFont.width + 2;
}
pString++;
}
}
/**
* \brief Returns the width & height in pixels that a string will occupy on the screen
* if drawn using LCDD_DrawString.
*
* \param pString String.
* \param pWidth Pointer for storing the string width (optional).
* \param pHeight Pointer for storing the string height (optional).
*
* \return String width in pixels.
*/
void LCDD_GetStringSize(
const uint8_t *pString,
uint32_t *pWidth,
uint32_t *pHeight)
{
uint32_t width = 0;
uint32_t height = gFont.height;
while (*pString != 0) {
if (*pString == '\n') {
height += gFont.height + 2;
}
else {
width += gFont.width + 2;
}
pString++;
}
if (width > 0) width -= 2;
if (pWidth) *pWidth = width;
if (pHeight) *pHeight = height;
}
/*
* \brief Draw a raw image at given position on LCD.
*
* \param x X-coordinate of image start.
* \param y Y-coordinate of image start.
* \param pImage Image buffer.
* \param width Image width.
* \param height Image height.
*/
void LCDD_DrawImage(
uint32_t x,
uint32_t y,
const uint8_t *pImage,
uint32_t width,
uint32_t height)
{
uint32_t row, col;
for(row = y; row < (y + height); row++) {
LCD_SetCursor(x, row);
LCD_WriteRAM_Prepare();
for(col = x; col < (x + width); col++) {
LCD_D() = *pImage++;
LCD_D() = *pImage++;
LCD_D() = *pImage++;
}
}
}
+114
View File
@@ -0,0 +1,114 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for draw function on LCD.
*
*/
#ifndef DRAW_H
#define DRAW_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Horizontal direction line definition */
#define DIRECTION_HLINE 0
/** Vertical direction line definition */
#define DIRECTION_VLINE 1
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void LCDD_Fill(uint32_t color);
extern void LCDD_DrawPixel(
uint32_t x,
uint32_t y,
uint32_t c);
extern uint32_t LCDD_ReadPixel(
uint32_t x,
uint32_t y);
extern void LCDD_DrawLine(
uint32_t x,
uint32_t y,
uint32_t length,
uint32_t direction,
uint32_t color);
extern void LCDD_DrawRectangle(
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height,
uint32_t color);
extern void LCDD_DrawRectangleWithFill(
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height,
uint32_t color);
extern void LCDD_DrawCircle(
uint32_t x,
uint32_t y,
uint32_t r,
uint32_t color);
extern void LCDD_DrawString(
uint32_t x,
uint32_t y,
const uint8_t *pString,
uint32_t color);
extern void LCDD_GetStringSize(
const uint8_t *pString,
uint32_t *pWidth,
uint32_t *pHeight);
extern void LCDD_DrawImage(
uint32_t x,
uint32_t y,
const uint8_t *pImage,
uint32_t width,
uint32_t height);
#endif /* #ifndef DRAW_H */
+95
View File
@@ -0,0 +1,95 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of draw font on LCD.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "color.h"
#include "font.h"
#include "draw.h"
#include "font10x14.h"
#include <utility/assert.h>
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** Global variable describing the font being instancied. */
const Font gFont = {10, 14};
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Draws an ASCII character on LCD.
*
* \param x X-coordinate of character upper-left corner.
* \param y Y-coordinate of character upper-left corner.
* \param c Character to output.
* \param color Character color.
*/
void LCDD_DrawChar(
uint32_t x,
uint32_t y,
uint8_t c,
uint32_t color)
{
uint32_t row, col;
SANITY_CHECK((c >= 0x20) && (c <= 0x7F));
for (col = 0; col < 10; col++) {
for (row = 0; row < 8; row++) {
if ((pCharset10x14[((c - 0x20) * 20) + col * 2] >> (7 - row)) & 0x1) {
LCDD_DrawPixel(x+col, y+row, color);
}
}
for (row = 0; row < 6; row++) {
if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1) {
LCDD_DrawPixel(x+col, y+row+8, color);
}
}
}
}
+92
View File
@@ -0,0 +1,92 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for draw font on LCD.
*
*/
/**
*
* \section Purpose
*
* The font.h files declares a font structure and a LCDD_DrawChar function
* that must be implemented by a font definition file to be used with the
* LCDD_DrawString method of draw.h.
*
* The font10x14.c implements the necessary variable and function for a 10x14
* font.
*
* \section Usage
*
* -# Declare a gFont global variable with the necessary Font information.
* -# Implement an LCDD_DrawChar function which displays the specified
* character on the LCD.
* -# Use the LCDD_DrawString method defined in draw.h to display a complete
* string.
*/
#ifndef FONT_H
#define FONT_H
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** Describes the font (width, height, supported characters, etc.) used by
* the LCD driver draw API.
*/
typedef struct _Font {
/* Font width in pixels. */
uint8_t width;
/* Font height in pixels. */
uint8_t height;
} Font;
/*----------------------------------------------------------------------------
* Variables
*----------------------------------------------------------------------------*/
/** Global variable describing the font being instancied. */
extern const Font gFont;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void LCDD_DrawChar(
uint32_t x,
uint32_t y,
uint8_t c,
uint32_t color);
#endif /* #ifndef FONT_H */
@@ -0,0 +1,236 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Font 10x14 table definition.
*
*/
#ifndef LCD_FONT_10x14_H
#define LCD_FONT_10x14_H
/** Char set of font 10x14 */
const uint8_t pCharset10x14[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xCC,
0xFF, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0C, 0xC0, 0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0,
0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0,
0x0C, 0x60, 0x1E, 0x70, 0x3F, 0x30, 0x33, 0x30, 0xFF, 0xFC,
0xFF, 0xFC, 0x33, 0x30, 0x33, 0xF0, 0x39, 0xE0, 0x18, 0xC0,
0x60, 0x00, 0xF0, 0x0C, 0xF0, 0x3C, 0x60, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x3C, 0x18, 0xF0, 0x3C, 0xC0, 0x3C, 0x00, 0x18,
0x3C, 0xF0, 0x7F, 0xF8, 0xC3, 0x1C, 0xC7, 0x8C, 0xCF, 0xCC,
0xDC, 0xEC, 0x78, 0x78, 0x30, 0x30, 0x00, 0xFC, 0x00, 0xCC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0xEC, 0x00,
0xF8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x3F, 0xF0, 0x78, 0x78,
0x60, 0x18, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0x60, 0x18,
0x78, 0x78, 0x3F, 0xF0, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x60, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x3F, 0xF8,
0x3F, 0xF8, 0x03, 0x80, 0x07, 0xC0, 0x0E, 0xE0, 0x0C, 0x60,
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0,
0x3F, 0xF0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x00, 0x44, 0x00, 0xEC, 0x00, 0xF8, 0x00, 0x70, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x00, 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x00,
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0xFC, 0xC1, 0xCC, 0xC3, 0x8C,
0xC7, 0x0C, 0xCE, 0x0C, 0xFC, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x70, 0x0C, 0xFF, 0xFC,
0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x30, 0x0C, 0x70, 0x1C, 0xE0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC,
0xC1, 0xCC, 0xC3, 0x8C, 0xE7, 0x0C, 0x7E, 0x0C, 0x3C, 0x0C,
0x30, 0x30, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x7F, 0xF8, 0x3C, 0xF0,
0x03, 0xC0, 0x07, 0xC0, 0x0E, 0xC0, 0x1C, 0xC0, 0x38, 0xC0,
0x70, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xC0, 0x00, 0xC0,
0xFC, 0x30, 0xFC, 0x38, 0xCC, 0x1C, 0xCC, 0x0C, 0xCC, 0x0C,
0xCC, 0x0C, 0xCC, 0x0C, 0xCE, 0x1C, 0xC7, 0xF8, 0xC3, 0xF0,
0x3F, 0xF0, 0x7F, 0xF8, 0xE3, 0x1C, 0xC3, 0x0C, 0xC3, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x9C, 0x71, 0xF8, 0x30, 0xF0,
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC3, 0xFC,
0xC7, 0xFC, 0xCE, 0x00, 0xDC, 0x00, 0xF8, 0x00, 0xF0, 0x00,
0x3C, 0xF0, 0x7F, 0xF8, 0xE7, 0x9C, 0xC3, 0x0C, 0xC3, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
0x3C, 0x00, 0x7E, 0x00, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x1C,
0xC3, 0x38, 0xC3, 0x70, 0xE7, 0xE0, 0x7F, 0xC0, 0x3F, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x3C, 0xF0,
0x3C, 0xF0, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x44, 0x3C, 0xEC,
0x3C, 0xF8, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0,
0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0x00, 0x00,
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
0x00, 0x00, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x38, 0x70,
0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
0x30, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0xC1, 0xEC,
0xC3, 0xEC, 0xC3, 0x00, 0xE6, 0x00, 0x7E, 0x00, 0x3C, 0x00,
0x30, 0xF0, 0x71, 0xF8, 0xE3, 0x9C, 0xC3, 0x0C, 0xC3, 0xFC,
0xC3, 0xFC, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
0x3F, 0xFC, 0x7F, 0xFC, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xC0, 0x7F, 0xFC, 0x3F, 0xFC,
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x30, 0x30,
0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC0, 0x00, 0xC0, 0x00,
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x73, 0xF8, 0x33, 0xF0,
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x00, 0x38, 0xC0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC0, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0, 0xC0, 0x00, 0xC0, 0x00,
0xFF, 0xFC, 0xFF, 0xFC, 0x07, 0x80, 0x07, 0x80, 0x0F, 0xC0,
0x1C, 0xE0, 0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C,
0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
0xFF, 0xFC, 0xFF, 0xFC, 0x70, 0x00, 0x38, 0x00, 0x1F, 0x00,
0x1F, 0x00, 0x38, 0x00, 0x70, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
0xFF, 0xFC, 0xFF, 0xFC, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,
0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0xFF, 0xFC, 0xFF, 0xFC,
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
0xC3, 0x00, 0xC3, 0x00, 0xE7, 0x00, 0x7E, 0x00, 0x3C, 0x00,
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0xCC,
0xC0, 0xEC, 0xC0, 0x7C, 0xE0, 0x38, 0x7F, 0xFC, 0x3F, 0xEC,
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x80, 0xC3, 0x80,
0xC3, 0xC0, 0xC3, 0xC0, 0xE7, 0x70, 0x7E, 0x3C, 0x3C, 0x1C,
0x3C, 0x18, 0x7E, 0x1C, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x9C, 0xE1, 0xF8, 0x60, 0xF0,
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0xFC,
0xFF, 0xFC, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
0xFF, 0xC0, 0xFF, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0xFF, 0xE0, 0xFF, 0xC0,
0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0xF8,
0x00, 0xF8, 0x00, 0x3C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
0xF0, 0x3C, 0xF8, 0x7C, 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80,
0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0, 0xF8, 0x7C, 0xF0, 0x3C,
0xFC, 0x00, 0xFE, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xFC,
0x01, 0xFC, 0x03, 0x80, 0x07, 0x00, 0xFE, 0x00, 0xFC, 0x00,
0xC0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC, 0xC1, 0xCC, 0xC3, 0x8C,
0xC7, 0x0C, 0xCE, 0x0C, 0xDC, 0x0C, 0xF8, 0x0C, 0xF0, 0x0C,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C,
0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x30,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C, 0x00,
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00,
0x38, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x06, 0x78, 0x0E, 0xFC, 0x0C, 0xCC, 0x0C, 0xCC,
0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xCC, 0x07, 0xFC, 0x03, 0xF8,
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C,
0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9C, 0x01, 0xF8, 0x00, 0xF0,
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30,
0x00, 0xF0, 0x01, 0xF8, 0x03, 0x9C, 0x03, 0x0C, 0x03, 0x0C,
0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0xFF, 0xFC, 0xFF, 0xFC,
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0xDC, 0x0C, 0xCC, 0x0C, 0xCC,
0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xDC, 0x07, 0xD8, 0x03, 0x90,
0x00, 0x00, 0x03, 0x00, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x00,
0xE3, 0x00, 0x70, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xDC, 0x0F, 0xF8, 0x07, 0xF0,
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x03, 0x00, 0x03, 0x80, 0x01, 0xFC, 0x00, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFC,
0x1B, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C,
0x00, 0x0C, 0x00, 0x1C, 0xCF, 0xF8, 0xCF, 0xF0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xE0, 0x01, 0xE0,
0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFC, 0x0F, 0xFC, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xC0,
0x03, 0xC0, 0x07, 0x00, 0x0E, 0x00, 0x0F, 0xFC, 0x0F, 0xFC,
0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x00, 0x07, 0x00, 0x0E, 0x00,
0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0xFC, 0x03, 0xFC,
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0xF8, 0x03, 0xF0,
0x0F, 0xFC, 0x0F, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00,
0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xFC, 0x0F, 0xFC,
0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00,
0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x00,
0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xFC, 0x0E, 0x78, 0x06, 0x30,
0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xFF, 0xF0, 0xFF, 0xF8,
0x0C, 0x1C, 0x0C, 0x1C, 0x0C, 0x38, 0x0C, 0x30, 0x00, 0x00,
0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
0x0F, 0xC0, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x0F, 0xE0, 0x0F, 0xC0,
0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0xF8,
0x00, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0xF0, 0x01, 0xE0,
0x01, 0xE0, 0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C,
0x0C, 0x00, 0x0E, 0x00, 0x07, 0x0C, 0x03, 0x9C, 0x01, 0xF8,
0x01, 0xF0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x0C, 0x00,
0x0C, 0x0C, 0x0C, 0x1C, 0x0C, 0x3C, 0x0C, 0x7C, 0x0C, 0xEC,
0x0D, 0xCC, 0x0F, 0x8C, 0x0F, 0x0C, 0x0E, 0x0C, 0x0C, 0x0C,
0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x3F, 0xF0, 0x7C, 0xF8,
0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00,
0x03, 0x0C, 0x03, 0x0C, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x0C,
0xC3, 0x0C, 0xC0, 0x0C, 0xE0, 0x0C, 0x70, 0x0C, 0x30, 0x0C,
0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C,
0x7C, 0xF8, 0x3F, 0xF0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC,
0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC
};
#endif /* #ifdef _LCD_FONT_10x14_h */
+149
View File
@@ -0,0 +1,149 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of LCD driver, Include LCD initialization,
* LCD on/off and LCD backlight control.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "lcdd.h"
#include <board.h>
#include <pmc/pmc.h>
#include <ili9325/ili9325.h>
#include <pio/pio.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initializes the LCD controller.
* Configure SMC to access LCD controller at 64MHz MCK.
*/
void LCDD_Initialize(void)
{
const Pin pPins[] = {BOARD_LCD_PINS};
Smc *pSmc = SMC;
/* Enable pins */
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
/* Enable peripheral clock */
PMC_EnablePeripheral(ID_SMC);
/* EBI SMC Configuration */
pSmc->SMC_CS_NUMBER[1].SMC_SETUP = 0
| ((2 << 0) & SMC_SETUP1_NWE_SETUP)
| ((2 << 8) & SMC_SETUP1_NCS_WR_SETUP)
| ((2 << 16) & SMC_SETUP1_NRD_SETUP)
| ((2 << 24) & SMC_SETUP1_NCS_RD_SETUP)
;
pSmc->SMC_CS_NUMBER[1].SMC_PULSE = 0
| ((4 << 0) & SMC_PULSE1_NWE_PULSE)
| ((4 << 8) & SMC_PULSE1_NCS_WR_PULSE)
| ((10 << 16) & SMC_PULSE1_NRD_PULSE)
| ((10 << 24) & SMC_PULSE1_NCS_RD_PULSE)
;
pSmc->SMC_CS_NUMBER[1].SMC_CYCLE = 0
| ((10 << 0) & SMC_CYCLE1_NWE_CYCLE)
| ((22 << 16) & SMC_CYCLE1_NRD_CYCLE)
;
pSmc->SMC_CS_NUMBER[1].SMC_MODE = 0
| (SMC_MODE1_READ_MODE)
| (SMC_MODE1_WRITE_MODE)
| (0) /* Set 8 bit width. TODO: replace with definition in device header file */
;
/* Initialize LCD controller */
LCD_Initialize();
/* Set LCD backlight */
LCDD_SetBacklight(2);
}
/**
* \brief Turn on the LCD.
*/
void LCDD_On(void)
{
LCD_On();
}
/**
* \brief Turn off the LCD.
*/
void LCDD_Off(void)
{
LCD_Off();
}
/**
* \brief Set the backlight of the LCD.
*
* \param level Backlight brightness level [1..16], 1 means maximum brightness.
*/
void LCDD_SetBacklight (uint32_t level)
{
uint32_t i;
const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
/* Ensure valid level */
level = (level < 1) ? 1 : level;
level = (level > 16) ? 16 : level;
/* Enable pins */
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
/* Switch off backlight */
PIO_Clear(pPins);
i = 600 * (BOARD_MCK / 1000000); /* wait for at least 500us */
while(i--);
/* Set new backlight level */
for (i = 0; i < level; i++) {
PIO_Clear(pPins);
PIO_Clear(pPins);
PIO_Clear(pPins);
PIO_Set(pPins);
PIO_Set(pPins);
PIO_Set(pPins);
}
}
+52
View File
@@ -0,0 +1,52 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for LCD driver.
*
*/
#ifndef LCDD_H
#define LCDD_H
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void LCDD_Initialize(void);
extern void LCDD_On(void);
extern void LCDD_Off(void);
extern void LCDD_SetBacklight (uint32_t step);
#endif /* #ifndef LCDD_H */
+464
View File
@@ -0,0 +1,464 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/// \file
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "pio.h"
#include <board.h>
#include <pmc/pmc.h>
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures one or more pin(s) of a PIO controller as being controlled by
/// peripheral A. Optionally, the corresponding internal pull-up(s) can be
/// enabled.
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask of one or more pin(s) to configure.
/// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
/// configured.
//------------------------------------------------------------------------------
static void PIO_SetPeripheralA(
Pio *pio,
unsigned int mask,
unsigned char enablePullUp)
{
unsigned int abcdsr;
// Disable interrupts on the pin(s)
pio->PIO_IDR = mask;
// Enable the pull-up(s) if necessary
if (enablePullUp) {
pio->PIO_PUER = mask;
}
else {
pio->PIO_PUDR = mask;
}
abcdsr = pio->PIO_ABCDSR[0];
pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
abcdsr = pio->PIO_ABCDSR[1];
pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
pio->PIO_PDR = mask;
}
//------------------------------------------------------------------------------
/// Configures one or more pin(s) of a PIO controller as being controlled by
/// peripheral B. Optionally, the corresponding internal pull-up(s) can be
/// enabled.
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask of one or more pin(s) to configure.
/// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
/// configured.
//------------------------------------------------------------------------------
static void PIO_SetPeripheralB(
Pio *pio,
unsigned int mask,
unsigned char enablePullUp)
{
unsigned int abcdsr;
// Disable interrupts on the pin(s)
pio->PIO_IDR = mask;
// Enable the pull-up(s) if necessary
if (enablePullUp) {
pio->PIO_PUER = mask;
}
else {
pio->PIO_PUDR = mask;
}
abcdsr = pio->PIO_ABCDSR[0];
pio->PIO_ABCDSR[0] = (mask | abcdsr);
abcdsr = pio->PIO_ABCDSR[1];
pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
pio->PIO_PDR = mask;
}
//------------------------------------------------------------------------------
/// Configures one or more pin(s) of a PIO controller as being controlled by
/// peripheral C. Optionally, the corresponding internal pull-up(s) can be
/// enabled.
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask of one or more pin(s) to configure.
/// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
/// configured.
//------------------------------------------------------------------------------
static void PIO_SetPeripheralC(
Pio *pio,
unsigned int mask,
unsigned char enablePullUp)
{
unsigned int abcdsr;
// Disable interrupts on the pin(s)
pio->PIO_IDR = mask;
// Enable the pull-up(s) if necessary
if (enablePullUp) {
pio->PIO_PUER = mask;
}
else {
pio->PIO_PUDR = mask;
}
abcdsr = pio->PIO_ABCDSR[0];
pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
abcdsr = pio->PIO_ABCDSR[1];
pio->PIO_ABCDSR[1] = (mask | abcdsr);
pio->PIO_PDR = mask;
}
//------------------------------------------------------------------------------
/// Configures one or more pin(s) of a PIO controller as being controlled by
/// peripheral D. Optionally, the corresponding internal pull-up(s) can be
/// enabled.
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask of one or more pin(s) to configure.
/// \param enablePullUp Indicates if the pin(s) internal pull-up shall be
/// configured.
//------------------------------------------------------------------------------
static void PIO_SetPeripheralD(
Pio *pio,
unsigned int mask,
unsigned char enablePullUp)
{
unsigned int abcdsr;
// Disable interrupts on the pin(s)
pio->PIO_IDR = mask;
// Enable the pull-up(s) if necessary
if (enablePullUp) {
pio->PIO_PUER = mask;
}
else {
pio->PIO_PUDR = mask;
}
abcdsr = pio->PIO_ABCDSR[0];
pio->PIO_ABCDSR[0] = (mask | abcdsr);
abcdsr = pio->PIO_ABCDSR[1];
pio->PIO_ABCDSR[1] = (mask | abcdsr);
pio->PIO_PDR = mask;
}
//------------------------------------------------------------------------------
/// Configures one or more pin(s) or a PIO controller as inputs. Optionally,
/// the corresponding internal pull-up(s) and glitch filter(s) can be
/// enabled.
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask indicating which pin(s) to configure as input(s).
/// \param enablePullUp Indicates if the internal pull-up(s) must be enabled.
/// \param enableFilter Indicates if the glitch filter(s) must be enabled.
//------------------------------------------------------------------------------
static void PIO_SetInput(
Pio *pio,
unsigned int mask,
unsigned char attribute)
{
// Disable interrupts
pio->PIO_IDR = mask;
// Enable pull-up(s) if necessary
if (attribute & PIO_PULLUP)
pio->PIO_PUER = mask;
else
pio->PIO_PUDR = mask;
// Enable de-glitch(s) if necessary
if (attribute & PIO_DEGLITCH)
pio->PIO_IFER = mask;
else
pio->PIO_IFDR = mask;
// Enable de-bounce if necessary
if (attribute & PIO_DEBOUNCE) {
pio->PIO_DIFSR = mask;
}
// Configure pin as input
pio->PIO_ODR = mask;
pio->PIO_PER = mask;
}
//------------------------------------------------------------------------------
/// Configures one or more pin(s) of a PIO controller as outputs, with the
/// given default value. Optionally, the multi-drive feature can be enabled
/// on the pin(s).
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask indicating which pin(s) to configure.
/// \param defaultValue Default level on the pin(s).
/// \param enableMultiDrive Indicates if the pin(s) shall be configured as
/// open-drain.
/// \param enablePullUp Indicates if the pin shall have its pull-up activated.
//------------------------------------------------------------------------------
static void PIO_SetOutput(
Pio *pio,
unsigned int mask,
unsigned char defaultValue,
unsigned char enableMultiDrive,
unsigned char enablePullUp)
{
// Disable interrupts
pio->PIO_IDR = mask;
// Enable pull-up(s) if necessary
if (enablePullUp) {
pio->PIO_PUER = mask;
}
else {
pio->PIO_PUDR = mask;
}
// Enable multi-drive if necessary
if (enableMultiDrive) {
pio->PIO_MDER = mask;
}
else {
pio->PIO_MDDR = mask;
}
// Set default value
if (defaultValue) {
pio->PIO_SODR = mask;
}
else {
pio->PIO_CODR = mask;
}
// Configure pin(s) as output(s)
pio->PIO_OER = mask;
pio->PIO_PER = mask;
}
//------------------------------------------------------------------------------
/// Configures interrupt mode for input Pins
/// \param pio Pointer to a PIO controller.
/// \param mask Bitmask indicating which pin(s) to configure.
/// \param additionnalItMode Enable Pio Additionnal It Mode.
/// \param edgeMode Enable the edge mode.
/// \param risingEdgeOrHighLevel Enable IT on rising edge or high level.
//------------------------------------------------------------------------------
static void PIO_SetInterrupt(
Pio *pio,
unsigned int mask,
unsigned char additionnalItMode,
unsigned char edgeMode,
unsigned char risingEdgeOrHighLevel)
{
/* Configure the Interrupt mode in the PIO controller */
if (additionnalItMode) {
/* enable additional interrupt mode */
pio->PIO_AIMER = mask;
/* if bit field of selected pin is 1, set as Rising Edge/High level detection event */
if (risingEdgeOrHighLevel)
pio->PIO_REHLSR = mask;
else
pio->PIO_FELLSR = mask;
/* if bit field of selected pin is 1, set as edge detection source */
if (edgeMode)
pio->PIO_ESR = mask;
else
pio->PIO_LSR = mask;
} else {
/* disable additional interrupt mode */
pio->PIO_AIMDR = mask;
}
}
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures a list of Pin instances, each of which can either hold a single
/// pin or a group of pins, depending on the mask value; all pins are configured
/// by this function. The size of the array must also be provided and is easily
/// computed using PIO_LISTSIZE whenever its length is not known in advance.
/// \param list Pointer to a list of Pin instances.
/// \param size Size of the Pin list (calculated using PIO_LISTSIZE).
/// \return 1 if the pins have been configured properly; otherwise 0.
//------------------------------------------------------------------------------
unsigned char PIO_Configure(const Pin *list, unsigned int size)
{
// Configure pins
while (size > 0) {
switch (list->type) {
case PIO_PERIPH_A:
PIO_SetPeripheralA(list->pio,
list->mask,
(list->attribute & PIO_PULLUP) ? 1 : 0);
break;
case PIO_PERIPH_B:
PIO_SetPeripheralB(list->pio,
list->mask,
(list->attribute & PIO_PULLUP) ? 1 : 0);
break;
case PIO_PERIPH_C:
PIO_SetPeripheralC(list->pio,
list->mask,
(list->attribute & PIO_PULLUP) ? 1 : 0);
break;
case PIO_PERIPH_D:
PIO_SetPeripheralD(list->pio,
list->mask,
(list->attribute & PIO_PULLUP) ? 1 : 0);
break;
case PIO_INPUT:
PMC_EnablePeripheral(list->id);
PIO_SetInput(list->pio,
list->mask,
list->attribute);
PIO_SetInterrupt(list->pio,
list->mask,
(list->attribute & PIO_IT_AIME) ? 1 : 0,
(list->attribute & PIO_IT_EDGE) ? 1 : 0,
(list->attribute & PIO_IT_RE_OR_HL) ? 1 : 0);
break;
case PIO_OUTPUT_0:
case PIO_OUTPUT_1:
PIO_SetOutput(list->pio,
list->mask,
(list->type == PIO_OUTPUT_1),
(list->attribute & PIO_OPENDRAIN) ? 1 : 0,
(list->attribute & PIO_PULLUP) ? 1 : 0);
break;
default: return 0;
}
list++;
size--;
}
return 1;
}
//------------------------------------------------------------------------------
/// Sets a high output level on all the PIOs defined in the given Pin instance.
/// This has no immediate effects on PIOs that are not output, but the PIO
/// controller will memorize the value they are changed to outputs.
/// \param pin Pointer to a Pin instance describing one or more pins.
//------------------------------------------------------------------------------
void PIO_Set(const Pin *pin)
{
pin->pio->PIO_SODR = pin->mask;
}
//------------------------------------------------------------------------------
/// Sets a low output level on all the PIOs defined in the given Pin instance.
/// This has no immediate effects on PIOs that are not output, but the PIO
/// controller will memorize the value they are changed to outputs.
/// \param pin Pointer to a Pin instance describing one or more pins.
//------------------------------------------------------------------------------
void PIO_Clear(const Pin *pin)
{
pin->pio->PIO_CODR = pin->mask;
}
//------------------------------------------------------------------------------
/// Returns 1 if one or more PIO of the given Pin instance currently have a high
/// level; otherwise returns 0. This method returns the actual value that is
/// being read on the pin. To return the supposed output value of a pin, use
/// PIO_GetOutputDataStatus() instead.
/// \param pin Pointer to a Pin instance describing one or more pins.
/// \return 1 if the Pin instance contains at least one PIO that currently has
/// a high level; otherwise 0.
//------------------------------------------------------------------------------
unsigned char PIO_Get(const Pin *pin)
{
unsigned int reg;
if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1)) {
reg = pin->pio->PIO_ODSR;
}
else {
reg = pin->pio->PIO_PDSR;
}
if ((reg & pin->mask) == 0) {
return 0;
}
else {
return 1;
}
}
//------------------------------------------------------------------------------
/// Returns 1 if one or more PIO of the given Pin are configured to output a
/// high level (even if they are not output).
/// To get the actual value of the pin, use PIO_Get() instead.
/// \param pin Pointer to a Pin instance describing one or more pins.
/// \return 1 if the Pin instance contains at least one PIO that is configured
/// to output a high level; otherwise 0.
//------------------------------------------------------------------------------
unsigned char PIO_GetOutputDataStatus(const Pin *pin)
{
if ((pin->pio->PIO_ODSR & pin->mask) == 0) {
return 0;
}
else {
return 1;
}
}
+215
View File
@@ -0,0 +1,215 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
/// \file
///
/// \par Purpose
///
/// This file provides a basic API for PIO configuration and usage of
/// user-controlled pins. Please refer to the board.h file for a list of
/// available pin definitions.
///
/// \par Usage
///
/// -# Define a constant pin description array such as the following one, using
/// the existing definitions provided by the board.h file if possible:
/// \code
/// const Pin pPins[] = {PIN_USART0_TXD, PIN_USART0_RXD};
/// \endcode
/// Alternatively, it is possible to add new pins by provided the full Pin
/// structure:
/// \code
/// // Pin instance to configure PA10 & PA11 as inputs with the internal
/// // pull-up enabled.
/// const Pin pPins = {
/// (1 << 10) | (1 << 11),
/// REG_PIOA,
/// ID_PIOA,
/// PIO_INPUT,
/// PIO_PULLUP
/// };
/// \endcode
/// -# Configure a pin array by calling PIO_Configure() with a pointer to the
/// array and its size (which is computed using the PIO_LISTSIZE macro).
/// -# Change and get the value of a user-controlled pin using the PIO_Set,
/// PIO_Clear and PIO_Get methods.
/// -# Get the level being currently output by a user-controlled pin configured
/// as an output using PIO_GetOutputDataStatus().
//------------------------------------------------------------------------------
#ifndef PIO_H
#define PIO_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <board.h>
//------------------------------------------------------------------------------
// Global Definitions
//------------------------------------------------------------------------------
/// The pin is controlled by the associated signal of peripheral A.
#define PIO_PERIPH_A 0
/// The pin is controlled by the associated signal of peripheral B.
#define PIO_PERIPH_B 1
/// The pin is controlled by the associated signal of peripheral C.
#define PIO_PERIPH_C 2
/// The pin is controlled by the associated signal of peripheral D.
#define PIO_PERIPH_D 3
/// The pin is an input.
#define PIO_INPUT 4
/// The pin is an output and has a default level of 0.
#define PIO_OUTPUT_0 5
/// The pin is an output and has a default level of 1.
#define PIO_OUTPUT_1 6
/// Default pin configuration (no attribute).
#define PIO_DEFAULT (0 << 0)
/// The internal pin pull-up is active.
#define PIO_PULLUP (1 << 0)
/// The internal glitch filter is active.
#define PIO_DEGLITCH (1 << 1)
/// The pin is open-drain.
#define PIO_OPENDRAIN (1 << 2)
/// The internal debouncing filter is active.
#define PIO_DEBOUNCE (1 << 3)
/// Enable additional interrupt modes.
#define PIO_IT_AIME (1 << 4)
/// Interrupt High Level/Rising Edge detection is active.
#define PIO_IT_RE_OR_HL (1 << 5)
/// Interrupt Edge detection is active.
#define PIO_IT_EDGE (1 << 6)
/// Low level interrupt is active
#define PIO_IT_LOW_LEVEL (0 | 0 | PIO_IT_AIME)
/// High level interrupt is active
#define PIO_IT_HIGH_LEVEL (PIO_IT_RE_OR_HL | 0 | PIO_IT_AIME)
/// Falling edge interrupt is active
#define PIO_IT_FALL_EDGE (0 | PIO_IT_EDGE | PIO_IT_AIME)
/// Rising edge interrupt is active
#define PIO_IT_RISE_EDGE (PIO_IT_RE_OR_HL | PIO_IT_EDGE | PIO_IT_AIME)
//------------------------------------------------------------------------------
// Global Macros
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Calculates the size of an array of Pin instances. The array must be defined
/// locally (i.e. not a pointer), otherwise the computation will not be correct.
/// \param pPins Local array of Pin instances.
/// \return Number of elements in array.
//------------------------------------------------------------------------------
#define PIO_LISTSIZE(pPins) (sizeof(pPins) / sizeof(Pin))
//------------------------------------------------------------------------------
// Global Types
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Describes the type and attribute of one PIO pin or a group of similar pins.
/// The #type# field can have the following values:
/// - PIO_PERIPH_A
/// - PIO_PERIPH_B
/// - PIO_OUTPUT_0
/// - PIO_OUTPUT_1
/// - PIO_INPUT
///
/// The #attribute# field is a bitmask that can either be set to PIO_DEFAULt,
/// or combine (using bitwise OR '|') any number of the following constants:
/// - PIO_PULLUP
/// - PIO_DEGLITCH
/// - PIO_DEBOUNCE
/// - PIO_OPENDRAIN
/// - PIO_IT_LOW_LEVEL
/// - PIO_IT_HIGH_LEVEL
/// - PIO_IT_FALL_EDGE
/// - PIO_IT_RISE_EDGE
//------------------------------------------------------------------------------
typedef struct {
/// Bitmask indicating which pin(s) to configure.
unsigned int mask;
/// Pointer to the PIO controller which has the pin(s).
Pio *pio;
/// Peripheral ID of the PIO controller which has the pin(s).
unsigned char id;
/// Pin type.
unsigned char type;
/// Pin attribute.
unsigned char attribute;
} Pin;
//------------------------------------------------------------------------------
// Global Access Macros
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures Glitch or Debouncing filter for input
/// \param pin Pointer to a Pin instance describing one or more pins.
/// \param cuttoff Cutt off frequency for debounce filter
//------------------------------------------------------------------------------
static inline void PIO_SetDebounceFilter(
const Pin *pin,
unsigned int cuttoff)
{
Pio *pio = pin->pio;
pio->PIO_DIFSR = pin->mask;//set Debouncing, 0 bit field no effect
pio->PIO_SCDR = ((32678/(2*(cuttoff))) - 1) & 0x3FFF;//the lowest 14 bits work
}
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
extern unsigned char PIO_Configure(const Pin *list, unsigned int size);
extern void PIO_Set(const Pin *pin);
extern void PIO_Clear(const Pin *pin);
extern unsigned char PIO_Get(const Pin *pin);
//extern unsigned int PIO_GetISR(const Pin *pin);
extern unsigned char PIO_GetOutputDataStatus(const Pin *pin);
extern void PIO_EnableDebounce(const Pin *pin, unsigned int clkDiv);
#endif //#ifndef PIO_H
+411
View File
@@ -0,0 +1,411 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/// \file
/// Disable traces for this file
#undef TRACE_LEVEL
#define TRACE_LEVEL 0
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "pio_it.h"
#include "pio.h"
#include <board.h>
#include <pmc/pmc.h>
#include <utility/assert.h>
#include <utility/trace.h>
#include <cmsis/core_cm3.h>
//------------------------------------------------------------------------------
// Local definitions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local types
//------------------------------------------------------------------------------
/* Define WEAK attribute */
#if defined ( __CC_ARM )
#define WEAK __attribute__ ((weak))
#elif defined ( __ICCARM__ )
#define WEAK __weak
#elif defined ( __GNUC__ )
#define WEAK __attribute__ ((weak))
#endif
//------------------------------------------------------------------------------
// Local variables
//------------------------------------------------------------------------------
typedef void (*PioHandler) (unsigned char id);
/* Default PIO handlers defined as weak functions which have to be redefined by
* the application */
WEAK void PIOA_Irq0Handler(unsigned char id) {}
WEAK void PIOA_Irq1Handler(unsigned char id) {}
WEAK void PIOA_Irq2Handler(unsigned char id) {}
WEAK void PIOA_Irq3Handler(unsigned char id) {}
WEAK void PIOA_Irq4Handler(unsigned char id) {}
WEAK void PIOA_Irq5Handler(unsigned char id) {}
WEAK void PIOA_Irq6Handler(unsigned char id) {}
WEAK void PIOA_Irq7Handler(unsigned char id) {}
WEAK void PIOA_Irq8Handler(unsigned char id) {}
WEAK void PIOA_Irq9Handler(unsigned char id) {}
WEAK void PIOA_Irq10Handler(unsigned char id) {}
WEAK void PIOA_Irq11Handler(unsigned char id) {}
WEAK void PIOA_Irq12Handler(unsigned char id) {}
WEAK void PIOA_Irq13Handler(unsigned char id) {}
WEAK void PIOA_Irq14Handler(unsigned char id) {}
WEAK void PIOA_Irq15Handler(unsigned char id) {}
WEAK void PIOA_Irq16Handler(unsigned char id) {}
WEAK void PIOA_Irq17Handler(unsigned char id) {}
WEAK void PIOA_Irq18Handler(unsigned char id) {}
WEAK void PIOA_Irq19Handler(unsigned char id) {}
WEAK void PIOA_Irq20Handler(unsigned char id) {}
WEAK void PIOA_Irq21Handler(unsigned char id) {}
WEAK void PIOA_Irq22Handler(unsigned char id) {}
WEAK void PIOA_Irq23Handler(unsigned char id) {}
WEAK void PIOA_Irq24Handler(unsigned char id) {}
WEAK void PIOA_Irq25Handler(unsigned char id) {}
WEAK void PIOA_Irq26Handler(unsigned char id) {}
WEAK void PIOA_Irq27Handler(unsigned char id) {}
WEAK void PIOA_Irq28Handler(unsigned char id) {}
WEAK void PIOA_Irq29Handler(unsigned char id) {}
WEAK void PIOA_Irq30Handler(unsigned char id) {}
WEAK void PIOA_Irq31Handler(unsigned char id) {}
/** pioAHandlers records ISR routines for each PIO Id for PIO controller A */
static const PioHandler pioAHandlers[32] = {
(PioHandler) PIOA_Irq0Handler, /**< PA0 IT Handler */
(PioHandler) PIOA_Irq1Handler, /**< PA1 IT Handler */
(PioHandler) PIOA_Irq2Handler, /**< PA2 IT Handler */
(PioHandler) PIOA_Irq3Handler, /**< PA3 IT Handler */
(PioHandler) PIOA_Irq4Handler, /**< PA4 IT Handler */
(PioHandler) PIOA_Irq5Handler, /**< PA5 IT Handler */
(PioHandler) PIOA_Irq6Handler, /**< PA6 IT Handler */
(PioHandler) PIOA_Irq7Handler, /**< PA7 IT Handler */
(PioHandler) PIOA_Irq8Handler, /**< PA8 IT Handler */
(PioHandler) PIOA_Irq9Handler, /**< PA9 IT Handler */
(PioHandler) PIOA_Irq10Handler, /**< PA10 IT Handler */
(PioHandler) PIOA_Irq11Handler, /**< PA11 IT Handler */
(PioHandler) PIOA_Irq12Handler, /**< PA12 IT Handler */
(PioHandler) PIOA_Irq13Handler, /**< PA13 IT Handler */
(PioHandler) PIOA_Irq14Handler, /**< PA14 IT Handler */
(PioHandler) PIOA_Irq15Handler, /**< PA15 IT Handler */
(PioHandler) PIOA_Irq16Handler, /**< PA16 IT Handler */
(PioHandler) PIOA_Irq17Handler, /**< PA17 IT Handler */
(PioHandler) PIOA_Irq18Handler, /**< PA18 IT Handler */
(PioHandler) PIOA_Irq19Handler, /**< PA19 IT Handler */
(PioHandler) PIOA_Irq20Handler, /**< PA20 IT Handler */
(PioHandler) PIOA_Irq21Handler, /**< PA21 IT Handler */
(PioHandler) PIOA_Irq22Handler, /**< PA22 IT Handler */
(PioHandler) PIOA_Irq23Handler, /**< PA23 IT Handler */
(PioHandler) PIOA_Irq24Handler, /**< PA24 IT Handler */
(PioHandler) PIOA_Irq25Handler, /**< PA25 IT Handler */
(PioHandler) PIOA_Irq26Handler, /**< PA26 IT Handler */
(PioHandler) PIOA_Irq27Handler, /**< PA27 IT Handler */
(PioHandler) PIOA_Irq28Handler, /**< PA28 IT Handler */
(PioHandler) PIOA_Irq29Handler, /**< PA29 IT Handler */
(PioHandler) PIOA_Irq30Handler, /**< PA30 IT Handler */
(PioHandler) PIOA_Irq31Handler /**< PA31 IT Handler */
};
/* Default PIO handlers defined as weak functions which have to be redefined by
* the application */
WEAK void PIOB_Irq0Handler(unsigned char id) {}
WEAK void PIOB_Irq1Handler(unsigned char id) {}
WEAK void PIOB_Irq2Handler(unsigned char id) {}
WEAK void PIOB_Irq3Handler(unsigned char id) {}
WEAK void PIOB_Irq4Handler(unsigned char id) {}
WEAK void PIOB_Irq5Handler(unsigned char id) {}
WEAK void PIOB_Irq6Handler(unsigned char id) {}
WEAK void PIOB_Irq7Handler(unsigned char id) {}
WEAK void PIOB_Irq8Handler(unsigned char id) {}
WEAK void PIOB_Irq9Handler(unsigned char id) {}
WEAK void PIOB_Irq10Handler(unsigned char id) {}
WEAK void PIOB_Irq11Handler(unsigned char id) {}
WEAK void PIOB_Irq12Handler(unsigned char id) {}
WEAK void PIOB_Irq13Handler(unsigned char id) {}
WEAK void PIOB_Irq14Handler(unsigned char id) {}
WEAK void PIOB_Irq15Handler(unsigned char id) {}
WEAK void PIOB_Irq16Handler(unsigned char id) {}
WEAK void PIOB_Irq17Handler(unsigned char id) {}
WEAK void PIOB_Irq18Handler(unsigned char id) {}
WEAK void PIOB_Irq19Handler(unsigned char id) {}
WEAK void PIOB_Irq20Handler(unsigned char id) {}
WEAK void PIOB_Irq21Handler(unsigned char id) {}
WEAK void PIOB_Irq22Handler(unsigned char id) {}
WEAK void PIOB_Irq23Handler(unsigned char id) {}
WEAK void PIOB_Irq24Handler(unsigned char id) {}
WEAK void PIOB_Irq25Handler(unsigned char id) {}
WEAK void PIOB_Irq26Handler(unsigned char id) {}
WEAK void PIOB_Irq27Handler(unsigned char id) {}
WEAK void PIOB_Irq28Handler(unsigned char id) {}
WEAK void PIOB_Irq29Handler(unsigned char id) {}
WEAK void PIOB_Irq30Handler(unsigned char id) {}
WEAK void PIOB_Irq31Handler(unsigned char id) {}
/** PIOBHandlers records ISR routines for each PIO Id for PIO controller A */
static const PioHandler pioBHandlers[32] = {
(PioHandler) PIOB_Irq0Handler, /**< PB0 IT Handler */
(PioHandler) PIOB_Irq1Handler, /**< PB1 IT Handler */
(PioHandler) PIOB_Irq2Handler, /**< PB2 IT Handler */
(PioHandler) PIOB_Irq3Handler, /**< PB3 IT Handler */
(PioHandler) PIOB_Irq4Handler, /**< PB4 IT Handler */
(PioHandler) PIOB_Irq5Handler, /**< PB5 IT Handler */
(PioHandler) PIOB_Irq6Handler, /**< PB6 IT Handler */
(PioHandler) PIOB_Irq7Handler, /**< PB7 IT Handler */
(PioHandler) PIOB_Irq8Handler, /**< PB8 IT Handler */
(PioHandler) PIOB_Irq9Handler, /**< PB9 IT Handler */
(PioHandler) PIOB_Irq10Handler, /**< PB10 IT Handler */
(PioHandler) PIOB_Irq11Handler, /**< PB11 IT Handler */
(PioHandler) PIOB_Irq12Handler, /**< PB12 IT Handler */
(PioHandler) PIOB_Irq13Handler, /**< PB13 IT Handler */
(PioHandler) PIOB_Irq14Handler, /**< PB14 IT Handler */
(PioHandler) PIOB_Irq15Handler, /**< PB15 IT Handler */
(PioHandler) PIOB_Irq16Handler, /**< PB16 IT Handler */
(PioHandler) PIOB_Irq17Handler, /**< PB17 IT Handler */
(PioHandler) PIOB_Irq18Handler, /**< PB18 IT Handler */
(PioHandler) PIOB_Irq19Handler, /**< PB19 IT Handler */
(PioHandler) PIOB_Irq20Handler, /**< PB20 IT Handler */
(PioHandler) PIOB_Irq21Handler, /**< PB21 IT Handler */
(PioHandler) PIOB_Irq22Handler, /**< PB22 IT Handler */
(PioHandler) PIOB_Irq23Handler, /**< PB23 IT Handler */
(PioHandler) PIOB_Irq24Handler, /**< PB24 IT Handler */
(PioHandler) PIOB_Irq25Handler, /**< PB25 IT Handler */
(PioHandler) PIOB_Irq26Handler, /**< PB26 IT Handler */
(PioHandler) PIOB_Irq27Handler, /**< PB27 IT Handler */
(PioHandler) PIOB_Irq28Handler, /**< PB28 IT Handler */
(PioHandler) PIOB_Irq29Handler, /**< PB29 IT Handler */
(PioHandler) PIOB_Irq30Handler, /**< PB30 IT Handler */
(PioHandler) PIOB_Irq31Handler /**< PB31 IT Handler */
};
/* Default PIO handlers defined as weak functions which have to be redefined by
* the application */
WEAK void PIOC_Irq0Handler(unsigned char id) {}
WEAK void PIOC_Irq1Handler(unsigned char id) {}
WEAK void PIOC_Irq2Handler(unsigned char id) {}
WEAK void PIOC_Irq3Handler(unsigned char id) {}
WEAK void PIOC_Irq4Handler(unsigned char id) {}
WEAK void PIOC_Irq5Handler(unsigned char id) {}
WEAK void PIOC_Irq6Handler(unsigned char id) {}
WEAK void PIOC_Irq7Handler(unsigned char id) {}
WEAK void PIOC_Irq8Handler(unsigned char id) {}
WEAK void PIOC_Irq9Handler(unsigned char id) {}
WEAK void PIOC_Irq10Handler(unsigned char id) {}
WEAK void PIOC_Irq11Handler(unsigned char id) {}
WEAK void PIOC_Irq12Handler(unsigned char id) {}
WEAK void PIOC_Irq13Handler(unsigned char id) {}
WEAK void PIOC_Irq14Handler(unsigned char id) {}
WEAK void PIOC_Irq15Handler(unsigned char id) {}
WEAK void PIOC_Irq16Handler(unsigned char id) {}
WEAK void PIOC_Irq17Handler(unsigned char id) {}
WEAK void PIOC_Irq18Handler(unsigned char id) {}
WEAK void PIOC_Irq19Handler(unsigned char id) {}
WEAK void PIOC_Irq20Handler(unsigned char id) {}
WEAK void PIOC_Irq21Handler(unsigned char id) {}
WEAK void PIOC_Irq22Handler(unsigned char id) {}
WEAK void PIOC_Irq23Handler(unsigned char id) {}
WEAK void PIOC_Irq24Handler(unsigned char id) {}
WEAK void PIOC_Irq25Handler(unsigned char id) {}
WEAK void PIOC_Irq26Handler(unsigned char id) {}
WEAK void PIOC_Irq27Handler(unsigned char id) {}
WEAK void PIOC_Irq28Handler(unsigned char id) {}
WEAK void PIOC_Irq29Handler(unsigned char id) {}
WEAK void PIOC_Irq30Handler(unsigned char id) {}
WEAK void PIOC_Irq31Handler(unsigned char id) {}
/** PIOCHandlers records ISR routines for each PIO Id for PIO controller A */
static const PioHandler pioCHandlers[32] = {
(PioHandler) PIOC_Irq0Handler, /**< PC0 IT Handler */
(PioHandler) PIOC_Irq1Handler, /**< PC1 IT Handler */
(PioHandler) PIOC_Irq2Handler, /**< PC2 IT Handler */
(PioHandler) PIOC_Irq3Handler, /**< PC3 IT Handler */
(PioHandler) PIOC_Irq4Handler, /**< PC4 IT Handler */
(PioHandler) PIOC_Irq5Handler, /**< PC5 IT Handler */
(PioHandler) PIOC_Irq6Handler, /**< PC6 IT Handler */
(PioHandler) PIOC_Irq7Handler, /**< PC7 IT Handler */
(PioHandler) PIOC_Irq8Handler, /**< PC8 IT Handler */
(PioHandler) PIOC_Irq9Handler, /**< PC9 IT Handler */
(PioHandler) PIOC_Irq10Handler, /**< PC10 IT Handler */
(PioHandler) PIOC_Irq11Handler, /**< PC11 IT Handler */
(PioHandler) PIOC_Irq12Handler, /**< PC12 IT Handler */
(PioHandler) PIOC_Irq13Handler, /**< PC13 IT Handler */
(PioHandler) PIOC_Irq14Handler, /**< PC14 IT Handler */
(PioHandler) PIOC_Irq15Handler, /**< PC15 IT Handler */
(PioHandler) PIOC_Irq16Handler, /**< PC16 IT Handler */
(PioHandler) PIOC_Irq17Handler, /**< PC17 IT Handler */
(PioHandler) PIOC_Irq18Handler, /**< PC18 IT Handler */
(PioHandler) PIOC_Irq19Handler, /**< PC19 IT Handler */
(PioHandler) PIOC_Irq20Handler, /**< PC20 IT Handler */
(PioHandler) PIOC_Irq21Handler, /**< PC21 IT Handler */
(PioHandler) PIOC_Irq22Handler, /**< PC22 IT Handler */
(PioHandler) PIOC_Irq23Handler, /**< PC23 IT Handler */
(PioHandler) PIOC_Irq24Handler, /**< PC24 IT Handler */
(PioHandler) PIOC_Irq25Handler, /**< PC25 IT Handler */
(PioHandler) PIOC_Irq26Handler, /**< PC26 IT Handler */
(PioHandler) PIOC_Irq27Handler, /**< PC27 IT Handler */
(PioHandler) PIOC_Irq28Handler, /**< PC28 IT Handler */
(PioHandler) PIOC_Irq29Handler, /**< PC29 IT Handler */
(PioHandler) PIOC_Irq30Handler, /**< PC30 IT Handler */
(PioHandler) PIOC_Irq31Handler /**< PC31 IT Handler */
};
//------------------------------------------------------------------------------
/// \brief Generic PIO Handler.
/// The NVIC branches to the PIOx_IrqHandler() registered in exeption.c
/// PIOx_IrqHandler() invokes PIO_IrqHandler which scans which id has triggered
/// an interrupt and call the corresponding routine for the Id (<=> for the pin)
/// \param pPio PIO controller base address.
/// \param pPioHandlers Constant table which contains IT routines for each PIO Id
//------------------------------------------------------------------------------
static void PIO_IrqHandler(Pio *pPio, const PioHandler *pPioHandlers)
{
unsigned int status, id;
status = pPio->PIO_ISR;
status &= pPio->PIO_IMR;
for (id = 0; id < 32; ++id) {
if (status & (1 << id)) {
pPioHandlers[id](id);
}
}
}
//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller A interrupt handler
/// Redefined PIOA interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
void PIOA_IrqHandler(void)
{
PIO_IrqHandler(PIOA, pioAHandlers);
}
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller B interrupt handler
/// Redefined PIOB interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
void PIOB_IrqHandler(void)
{
PIO_IrqHandler(PIOB, pioBHandlers);
}
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller C interrupt handler
/// Redefined PIOC interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
void PIOC_IrqHandler(void)
{
PIO_IrqHandler(PIOC, pioCHandlers);
}
//------------------------------------------------------------------------------
/// Enables the given interrupt source. The status
/// register of the corresponding PIO controller is cleared prior to enabling
/// the interrupt.
/// \param pPin Interrupt source to enable.
//------------------------------------------------------------------------------
void PIO_EnableIt(const Pin *pPin)
{
Pio* pio = pPin->pio;
TRACE_DEBUG("PIO_EnableIt()\n\r");
// SANITY_CHECK(pPin);
/* Enable the interrupt in the PIO controller */
pio->PIO_ISR;
pio->PIO_IER = pPin->mask;
}
//------------------------------------------------------------------------------
/// Disables a given interrupt source, with no added side effects.
/// \param pPin Interrupt source to disable.
//------------------------------------------------------------------------------
void PIO_DisableIt(const Pin *pPin)
{
Pio* pio = pPin->pio;
SANITY_CHECK(pPin);
TRACE_DEBUG("PIO_DisableIt()\n\r");
/* Disable the interrupt in the PIO controller */
pio->PIO_IDR = pPin->mask;
}
//------------------------------------------------------------------------------
/// \brief Initializes the PIO interrupt management logic
/// The desired priority of PIO interrupts must be provided.
/// Calling this function multiple times result in the reset of currently
/// configured interrupts.
/// \param priority PIO controller interrupts priority.
//------------------------------------------------------------------------------
void PIO_InitializeInterrupts(unsigned int priority)
{
TRACE_DEBUG("PIO_Initialize()\n\r");
// Configure PIO interrupt sources
TRACE_DEBUG("PIO_Initialize: Configuring PIOA\n\r");
PIOA->PIO_ISR;
PIOA->PIO_IDR = 0xFFFFFFFF;
NVIC_DisableIRQ(PIOA_IRQn);
NVIC_ClearPendingIRQ(PIOA_IRQn);
NVIC_SetPriority(PIOA_IRQn, priority);
NVIC_EnableIRQ(PIOA_IRQn);
TRACE_DEBUG("PIO_Initialize: Configuring PIOB\n\r");
PIOB->PIO_ISR;
PIOB->PIO_IDR = 0xFFFFFFFF;
NVIC_DisableIRQ(PIOB_IRQn);
NVIC_ClearPendingIRQ(PIOB_IRQn);
NVIC_SetPriority(PIOB_IRQn, priority);
NVIC_EnableIRQ(PIOB_IRQn);
TRACE_DEBUG("PIO_Initialize: Configuring PIOC\n\r");
PIOC->PIO_ISR;
PIOC->PIO_IDR = 0xFFFFFFFF;
NVIC_DisableIRQ(PIOC_IRQn);
NVIC_ClearPendingIRQ(PIOC_IRQn);
NVIC_SetPriority(PIOC_IRQn, priority);
NVIC_EnableIRQ(PIOC_IRQn);
}
+153
View File
@@ -0,0 +1,153 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
/// \file
///
/// \par Purpose
///
/// Configuration and handling of interrupts on PIO status changes. The API
/// provided here have several advantages over the traditional PIO interrupt
/// configuration approach:
/// - It is highly portable
/// - It automatically demultiplexes interrupts when multiples pins have been
/// configured on a single PIO controller
/// - It allows a group of pins to share the same interrupt
///
/// However, it also has several minor drawbacks that may prevent from using it
/// in particular applications:
/// - It enables the clocks of all PIO controllers
/// - PIO controllers all share the same interrupt handler, which does the
/// demultiplexing and can be slower than direct configuration
/// - It reserves space for a fixed number of interrupts, which can be
/// increased by modifying the appropriate constant in pio_it.c.
///
/// \par Usage
///
/// -# Initialize the PIO interrupt mechanism using PIO_InitializeInterrupts()
/// with the desired priority (0 ... 7).
/// -# Configure a status change interrupt on one or more pin(s) with
/// PIO_ConfigureIt().
/// -# Enable & disable interrupts on pins using PIO_EnableIt() and
/// PIO_DisableIt().
//------------------------------------------------------------------------------
#ifndef PIO_IT_H
#define PIO_IT_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "pio.h"
//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/// \file
/// Disable traces for this file
#undef TRACE_LEVEL
#define TRACE_LEVEL 0
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "pio_it.h"
#include "pio.h"
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller A interrupt handler
/// Redefined PIOA interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
extern void PIOA_IrqHandler(void);
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller B interrupt handler
/// Redefined PIOB interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
extern void PIOB_IrqHandler(void);
//------------------------------------------------------------------------------
/// \brief Parallel IO Controller C interrupt handler
/// Redefined PIOC interrupt handler for NVIC interrupt table.
//------------------------------------------------------------------------------
extern void PIOC_IrqHandler(void);
//------------------------------------------------------------------------------
/// Configures and enables the given interrupt source. The status
/// register of the corresponding PIO controller is cleared prior to enabling
/// the interrupt.
/// \param pPin Interrupt source to enable.
//------------------------------------------------------------------------------
extern void PIO_EnableIt(const Pin *pPin);
//------------------------------------------------------------------------------
/// Disables a given interrupt source, with no added side effects.
/// \param pPin Interrupt source to disable.
//------------------------------------------------------------------------------
extern void PIO_DisableIt(const Pin *pPin);
//------------------------------------------------------------------------------
/// \brief Initializes the PIO interrupt management logic
/// The desired priority of PIO interrupts must be provided.
/// Calling this function multiple times result in the reset of currently
/// configured interrupts.
/// \param priority PIO controller interrupts priority.
//------------------------------------------------------------------------------
extern void PIO_InitializeInterrupts(unsigned int priority);
#endif //#ifndef PIO_IT_H
@@ -0,0 +1,147 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <board.h>
#include "pio.h"
#include "pio_keypad.h"
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures keypad controller
/// \param pPIO Pointer to a PIO instance
/// \param config Configuration data for given pin,see head file for detail
//------------------------------------------------------------------------------
void PIO_KeyPadConfig(AT91S_PIO *pPIO, KeyPadConfig *config)
{
//enable/disable keypad controller
pPIO->PIO_KER = config->enable;
//if enable, set keypad matrix and debouncing
if(config->enable == TRUE) {
//set key matrix
pPIO->PIO_KRCR = (config->row | config->col<<8) ;
//set debouncing
pPIO->PIO_KDR = config->debouncing;
}
}
//------------------------------------------------------------------------------
/// Get Key Press/Release status
/// \param pPIO Pointer to a PIO instance
/// \param event Pointer to a instance of KeyEvent for storing keypad status
//------------------------------------------------------------------------------
void PIO_GetKeyStatus(AT91S_PIO *pPIO, KeyEvent *event)
{
int i,j;
//get key press event
event->kdEvent.press = (pPIO->KSR&0x1)?TRUE:FALSE;
event->kdEvent.keyPressNum = (pPIO->KSR>>8)&0x3;
j=event->kdEvent.keyPressNum+1;
for(i=0; i<j; i++) {
event->kdEvent.preKeyMatrix[i].row = ((pPIO->KKPR) >> (8*i)) & 0x7;
event->kdEvent.preKeyMatrix[i].col = ((pPIO->KKPR) >> (8*i+4)) & 0x7;
}
//get key release event
event->kuEvent.release = ((pPIO->KSR>>1) & 0x1)?TRUE:FALSE;
event->kuEvent.keyRelNum = (pPIO->KSR>>16)&0x3;
j=event->kdEvent.keyPressNum+1;
for(i=0;i<j;i++) {
event->kuEvent.relKeyMatrix[i].row = ((pPIO->KKRR) >> (8*i)) & 0x7;
event->kuEvent.relKeyMatrix[i].col = ((pPIO->KKRR) >> (8*i+4)) & 0x7;
}
}
//------------------------------------------------------------------------------
/// Enable keypad interrupt as Key Press Interrupt or Key Release Interrupt or both
/// \param pPIO Pointer to a PIO instance
/// \param mode Select key interrupt mode to enable,
/// 0x1 Key Press Interrupt
/// 0x2 Key Release Interrupt
/// 0x3 both of two type
//------------------------------------------------------------------------------
void PIO_KeypadEnableIt(AT91S_PIO *pPIO, unsigned int mode)
{
switch(mode){
case 1:PIO_KeyPadEnableKPIt(pPIO);
break;
case 2:PIO_KeyPadEnableKRIt(pPIO);
break;
case 3:PIO_KeyPadEnableKPIt(pPIO);
PIO_KeyPadEnableKRIt(pPIO);
break;
default:break;
}
}
//------------------------------------------------------------------------------
/// Disable Key Press Interrupt or Key Release Interrupt or both of them
/// \param pPIO Pointer to a PIO instance
/// \param mode Select key interrupt mode to disable,
/// 0x1 Key Press Interrupt
/// 0x2 Key Release Interrupt
/// 0x3 both of two type
//------------------------------------------------------------------------------
void PIO_KeypadDisableIt(AT91S_PIO *pPIO, unsigned int mode)
{
switch(mode){
case 1:PIO_KeyPadDisableKPIt(pPIO);
break;
case 2:PIO_KeyPadDisableKRIt(pPIO);
break;
case 3:PIO_KeyPadDisableKPIt(pPIO);
PIO_KeyPadDisableKRIt(pPIO);
break;
default:break;
}
}
@@ -0,0 +1,153 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
#ifndef PIO_KEYPAD_H
#define PIO_KEYPAD_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <board.h>
//------------------------------------------------------------------------------
// Global Definitions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Global Macros
//------------------------------------------------------------------------------
//enable keypad press interrupt
#define PIO_KeyPadEnableKPIt(pPIO) ((pPIO)->KIER = 1<<0)
//enable keypad release interrupt
#define PIO_KeyPadEnableKRIt(pPIO) ((pPIO)->KIER = 1<<1)
//disable keypad press interrupt
#define PIO_KeyPadDisableKPIt(pPIO) ((pPIO)->KIDR = 1<<0)
//disable keypad release interrupt
#define PIO_KeyPadDisableKRIt(pPIO) ((pPIO)->KIDR = 1<<1)
//enable keypad controller interrupt
#define PIO_KeyPadEnableIt(pPIO, mode) {switch(mode):\
case 1:PIO_KeyPadEnableKPIt(pPIO);break;\
case 2:PIO_KeyPadEnableKRIt(pPIO);break;\
case 3:PIO_KeyPadEnableKPIt(pPIO);\
PIO_KeyPadEnableKRIt(pPIO);break;\
default:break;\
}
//disable keypad controller interrupt
#define PIO_KeyPadDisableIt(pPIO, mode) {switch(mode):\
case 1:PIO_KeyPadDisableKPIt(pPIO);break;\
case 2:PIO_KeyPadDisableKRIt(pPIO);break;\
case 3:PIO_KeyPadDisableKPIt(pPIO);\
PIO_KeyPadDisableKRIt(pPIO);break;\
default:break;\
}
//get keypad controller interrupt mask
#define PIO_KeyPadGetItMask(pPIO) ((pPIO)->PIO_KIMR)
//------------------------------------------------------------------------------
/// Calculates the size of an array of Pin instances. The array must be defined
/// locally (i.e. not a pointer), otherwise the computation will not be correct.
/// \param pPins Local array of Pin instances.
/// \return Number of elements in array.
//------------------------------------------------------------------------------
#define PIO_LISTSIZE(pPins) (sizeof(pPins) / sizeof(Pin))
//------------------------------------------------------------------------------
// Global Types
//------------------------------------------------------------------------------
typedef enum {
FALSE,
TRUE
} bool;
typedef struct _KeyPadConfig {
bool enable;//keypad controller enable or disable
unsigned char col:3;//config column size
unsigned char row:3;//config row size
unsigned int debouncing;//config debouncing
} KeyPadConfig;
typedef struct _KeyColRow {
unsigned char row:3;
unsigned char col:3;
} KeyColRow;
typedef struct _KeyDownEvent {
bool press;//at least 1 pressed key detected, or 0
unsigned char keyPressNum;//simultaneously pressed key number
KeyColRow preKeyMatrix[4];//pressed key matrix
} KeyDownEvent;
typedef struct _KeyUpEvent {
bool release;//at least 1 released key detected, or 0
unsigned char keyRelNum;//simultaneously released key number
KeyColRow relKeyMatrix[4];//released key matrix
} KeyUpEvent;
typedef struct _KeyEvent {
KeyDownEvent kdEvent;
KeyUpEvent kuEvent;
} KeyEvent;
//------------------------------------------------------------------------------
// Global Access Macros
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
void PIO_KeyPadConfig(AT91S_PIO *pPIO, KeyPadConfig *config);
void PIO_GetKeyStatus(AT91S_PIO *pPIO, KeyEvent *event);
void PIO_KeypadEnableIt(AT91S_PIO *pio, unsigned int mode);
void PIO_KeypadDisableIt(AT91S_PIO *pio, unsigned int mode);
#endif //#ifndef PIO_KEYPAD_H
+143
View File
@@ -0,0 +1,143 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "pmc.h"
#include <board.h>
#include <utility/assert.h>
//------------------------------------------------------------------------------
// Local definitions
//------------------------------------------------------------------------------
#define MASK_STATUS0 0xFFFFFFFC
#define MASK_STATUS1 0xFFFFFFFF
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Enables the clock of a peripheral. The peripheral ID is used
* to identify which peripheral is targetted.
* \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
* \param id Peripheral ID (ID_xxx).
*/
void PMC_EnablePeripheral(unsigned int id)
{
SANITY_CHECK(id < 35);
if (id < 32) {
if ((PMC->PMC_PCSR0 & (1 << id)) == (1 << id)) {
TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" " %u is already enabled\n\r", id);
}
else {
PMC->PMC_PCER0 = 1 << id;
}
}
else {
id -= 32;
if ((PMC->PMC_PCSR1 & (1 << id)) == (1 << id)) {
TRACE_DEBUG("PMC_EnablePeripheral: clock of peripheral" " %u is already enabled\n\r", id + 32);
}
else {
PMC->PMC_PCER1 = 1 << id;
}
}
}
/**
* \brief Disables the clock of a peripheral. The peripheral ID is used
* to identify which peripheral is targetted.
* \note The ID must NOT be shifted (i.e. 1 << ID_xxx).
* \param id Peripheral ID (ID_xxx).
*/
void PMC_DisablePeripheral(unsigned int id)
{
SANITY_CHECK(id < 35);
if (id < 32) {
if ((PMC->PMC_PCSR0 & (1 << id)) != (1 << id)) {
TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral" " %u is not enabled\n\r", id);
}
else {
PMC->PMC_PCDR0 = 1 << id;
}
}
else {
id -= 32;
if ((PMC->PMC_PCSR1 & (1 << id)) != (1 << id)) {
TRACE_DEBUG("PMC_DisablePeripheral: clock of peripheral" " %u is not enabled\n\r", id + 32);
}
else {
PMC->PMC_PCDR1 = 1 << id;
}
}
}
/**
* \brief Enable all the periph clock via PMC
*/
void PMC_EnableAllPeripherals(void)
{
PMC->PMC_PCER0 = MASK_STATUS0;
while( (PMC->PMC_PCSR0 & MASK_STATUS0) != MASK_STATUS0);
PMC->PMC_PCER1 = MASK_STATUS1;
while( (PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1);
TRACE_DEBUG("Enable all periph clocks\n\r");
}
/**
* \brief Disable all the periph clock via PMC
*/
void PMC_DisableAllPeripherals(void)
{
PMC->PMC_PCDR0 = MASK_STATUS0;
while((PMC->PMC_PCSR0 & MASK_STATUS0) != 0);
PMC->PMC_PCDR1 = MASK_STATUS1;
while((PMC->PMC_PCSR1 & MASK_STATUS1) != 0);
TRACE_DEBUG("Disable all periph clocks\n\r");
}
/**
* \brief Get Periph Status for the given peripheral ID.
* \param id Peripheral ID (ID_xxx).
*/
unsigned int PMC_IsPeriphEnabled(unsigned int id)
{
SANITY_CHECK(id < 35);
if (id < 32) {
return (PMC->PMC_PCSR0 & (1 << id));
}
else {
return (PMC->PMC_PCSR1 & (1 << (id - 32)));
}
}
+62
View File
@@ -0,0 +1,62 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
#ifndef PMC_H
#define PMC_H
//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------
#if defined(at91sam7l64) || defined(at91sam7l128)
extern void PMC_SetFastWakeUpInputs(unsigned int inputs);
extern void PMC_DisableMainOscillator(void);
extern
#ifdef __ICCARM__
__ramfunc
#endif //__ICCARM__
void PMC_DisableMainOscillatorForWaitMode(void);
#endif // at91sam7l64 at91sam7l128
extern void PMC_DisableProcessorClock(void);
extern void PMC_EnablePeripheral(unsigned int id);
extern void PMC_DisablePeripheral(unsigned int id);
extern void PMC_CPUInIdleMode(void);
extern void PMC_EnableAllPeripherals(void);
extern void PMC_DisableAllPeripherals(void);
extern unsigned int PMC_IsAllPeriphEnabled(void);
extern unsigned int PMC_IsPeriphEnabled(unsigned int id);
#endif //#ifndef PMC_H
+648
View File
@@ -0,0 +1,648 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup pwm_module Working with PWM
* The PWM driver provides the interface to configure and use the PWM
* peripheral.
*
* The PWM macrocell controls square output waveforms of 4 channels.
* Characteristics of output waveforms such as period, duty-cycle,
* dead-time can be configured.\n
* Some of PWM channels can be linked together as synchronous channel and
* duty-cycle of synchronous channels can be updated by PDC automaticly.
*
* Before enabling the channels, they must have been configured first.
* The main settings include:
* <ul>
* <li>Configuration of the clock generator.</li>
* <li>Selection of the clock for each channel.</li>
* <li>Configuration of output waveform characteristics, such as period, duty-cycle etc.</li>
* <li>Configuration for synchronous channels if needed.</li>
* - Selection of the synchronous channels.
* - Selection of the moment when the WRDY flag and the corresponding PDC
* transfer request are set (PTRM and PTRCS in the PWM_SCM register).
* - Configuration of the update mode (UPDM in the PWM_SCM register).
* - Configuration of the update period (UPR in the PWM_SCUP register).
* </ul>
*
* After the channels is enabled, the user must use respective update registers
* to change the wave characteristics to prevent unexpected output waveform.
* i.e. PWM_CDTYUPDx register should be used if user want to change duty-cycle
* when the channel is enabled.
*
* For more accurate information, please look at the PWM section of the
* Datasheet.
*
* Related files :\n
* \ref pwmc.c\n
* \ref pwmc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of the Pulse Width Modulation Controller (PWM) peripheral.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
/* These headers were introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */
#include <stdint.h>
#include "pwmc.h"
#include <board.h>
#include <utility/assert.h>
#include <utility/trace.h>
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Finds a prescaler/divisor couple to generate the desired frequency
* from MCK.
*
* Returns the value to enter in PWM_CLK or 0 if the configuration cannot be
* met.
*
* \param frequency Desired frequency in Hz.
* \param mck Master clock frequency in Hz.
*/
static uint16_t FindClockConfiguration(
uint32_t frequency,
uint32_t mck)
{
uint32_t divisors[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
uint8_t divisor = 0;
uint32_t prescaler;
SANITY_CHECK(frequency < mck);
/* Find prescaler and divisor values */
prescaler = (mck / divisors[divisor]) / frequency;
while ((prescaler > 255) && (divisor < 11)) {
divisor++;
prescaler = (mck / divisors[divisor]) / frequency;
}
/* Return result */
if (divisor < 11) {
TRACE_DEBUG("Found divisor=%u and prescaler=%u for freq=%uHz\n\r",
divisors[divisor], prescaler, frequency);
return prescaler | (divisor << 8);
}
else {
return 0;
}
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Configures PWM a channel with the given parameters, basic configure function.
*
* The PWM controller must have been clocked in the PMC prior to calling this
* function.
* Beware: this function disables the channel. It waits until disable is effective.
*
* \param channel Channel number.
* \param prescaler Channel prescaler.
* \param alignment Channel alignment.
* \param polarity Channel polarity.
*/
void PWMC_ConfigureChannel(
uint8_t channel,
uint32_t prescaler,
uint32_t alignment,
uint32_t polarity)
{
SANITY_CHECK(prescaler < PWM_CMR0_CPRE_MCKB);
SANITY_CHECK((alignment & ~PWM_CMR0_CALG) == 0);
SANITY_CHECK((polarity & ~PWM_CMR0_CPOL) == 0);
/* Disable channel (effective at the end of the current period) */
if ((PWM->PWM_SR & (1 << channel)) != 0) {
PWM->PWM_DIS = 1 << channel;
while ((PWM->PWM_SR & (1 << channel)) != 0);
}
/* Configure channel */
PWM->PWM_CH_NUM[channel].PWM_CMR = prescaler | alignment | polarity;
}
/**
* \brief Configures PWM a channel with the given parameters, extend configure function.
*
* The PWM controller must have been clocked in the PMC prior to calling this
* function.
* Beware: this function disables the channel. It waits until disable is effective.
*
* \param channel Channel number.
* \param prescaler Channel prescaler.
* \param alignment Channel alignment.
* \param polarity Channel polarity.
* \param countEventSelect Channel counter event selection.
* \param DTEnable Channel dead time generator enable.
* \param DTHInverte Channel Dead-Time PWMHx output Inverted.
* \param DTLInverte Channel Dead-Time PWMHx output Inverted.
*/
void PWMC_ConfigureChannelExt(
uint8_t channel,
uint32_t prescaler,
uint32_t alignment,
uint32_t polarity,
uint32_t countEventSelect,
uint32_t DTEnable,
uint32_t DTHInverte,
uint32_t DTLInverte)
{
SANITY_CHECK(prescaler < PWM_CMR0_CPRE_MCKB);
SANITY_CHECK((alignment & ~PWM_CMR0_CALG) == 0);
SANITY_CHECK((polarity & ~PWM_CMR0_CPOL) == 0);
SANITY_CHECK((countEventSelect & ~PWM_CMR0_CES) == 0);
SANITY_CHECK((DTEnable & ~PWM_CMR0_DTE) == 0);
SANITY_CHECK((DTHInverte & ~PWM_CMR0_DTHI) == 0);
SANITY_CHECK((DTLInverte & ~PWM_CMR0_DTLI) == 0);
/* Disable channel (effective at the end of the current period) */
if ((PWM->PWM_SR & (1 << channel)) != 0) {
PWM->PWM_DIS = 1 << channel;
while ((PWM->PWM_SR & (1 << channel)) != 0);
}
/* Configure channel */
PWM->PWM_CH_NUM[channel].PWM_CMR = prescaler | alignment | polarity |
countEventSelect | DTEnable | DTHInverte | DTLInverte;
}
/**
* \brief Configures PWM clocks A & B to run at the given frequencies.
*
* This function finds the best MCK divisor and prescaler values automatically.
*
* \param clka Desired clock A frequency (0 if not used).
* \param clkb Desired clock B frequency (0 if not used).
* \param mck Master clock frequency.
*/
void PWMC_ConfigureClocks(uint32_t clka, uint32_t clkb, uint32_t mck)
{
uint32_t mode = 0;
uint32_t result;
/* Clock A */
if (clka != 0) {
result = FindClockConfiguration(clka, mck);
ASSERT(result != 0, "-F- Could not generate the desired PWM frequency (%uHz)\n\r", (unsigned int)clka);
mode |= result;
}
/* Clock B */
if (clkb != 0) {
result = FindClockConfiguration(clkb, mck);
ASSERT(result != 0, "-F- Could not generate the desired PWM frequency (%uHz)\n\r", (unsigned int)clkb);
mode |= (result << 16);
}
/* Configure clocks */
TRACE_DEBUG("Setting PWM_CLK = 0x%08X\n\r", mode);
PWM->PWM_CLK = mode;
}
/**
* \brief Sets the period value used by a PWM channel.
*
* This function writes directly to the CPRD register if the channel is disabled;
* otherwise, it uses the update register CPRDUPD.
*
* \param channel Channel number.
* \param period Period value.
*/
void PWMC_SetPeriod(uint8_t channel, uint16_t period)
{
/* If channel is disabled, write to CPRD */
if ((PWM->PWM_SR & (1 << channel)) == 0) {
PWM->PWM_CH_NUM[channel].PWM_CPRD = period;
}
/* Otherwise use update register */
else {
PWM->PWM_CH_NUM[channel].PWM_CPRDUPD = period;
}
}
/**
* \brief Sets the duty cycle used by a PWM channel.
* This function writes directly to the CDTY register if the channel is disabled;
* otherwise it uses the update register CDTYUPD.
* Note that the duty cycle must always be inferior or equal to the channel
* period.
*
* \param channel Channel number.
* \param duty Duty cycle value.
*/
void PWMC_SetDutyCycle(uint8_t channel, uint16_t duty)
{
SANITY_CHECK(duty <= PWM->PWM_CH_NUM[channel].PWM_CPRD);
/* If channel is disabled, write to CDTY */
if ((PWM->PWM_SR & (1 << channel)) == 0) {
PWM->PWM_CH_NUM[channel].PWM_CDTY = duty;
}
/* Otherwise use update register */
else {
PWM->PWM_CH_NUM[channel].PWM_CDTYUPD = duty;
}
}
/**
* \brief Sets the dead time used by a PWM channel.
* This function writes directly to the DT register if the channel is disabled;
* otherwise it uses the update register DTUPD.
* Note that the dead time must always be inferior or equal to the channel
* period.
*
* \param channel Channel number.
* \param timeH Dead time value for PWMHx output.
* \param timeL Dead time value for PWMLx output.
*/
void PWMC_SetDeadTime(uint8_t channel, uint16_t timeH, uint16_t timeL)
{
SANITY_CHECK(timeH <= PWM->PWM_CH_NUM[channel].PWM_CPRD);
SANITY_CHECK(timeL <= PWM->PWM_CH_NUM[channel].PWM_CPRD);
/* If channel is disabled, write to DT */
if ((PWM->PWM_SR & (1 << channel)) == 0) {
PWM->PWM_CH_NUM[channel].PWM_DT = timeH | (timeL << 16);
}
/* Otherwise use update register */
else {
PWM->PWM_CH_NUM[channel].PWM_DTUPD = timeH | (timeL << 16);
}
}
/**
* \brief Configures Syncronous channel with the given parameters.
* Beware: At this time, the channels should be disabled.
*
* \param channels Bitwise OR of Syncronous channels.
* \param updateMode Syncronous channel update mode.
* \param requestMode PDC transfer request mode.
* \param requestComparisonSelect PDC transfer request comparison selection.
*/
void PWMC_ConfigureSyncChannel(
uint32_t channels,
uint32_t updateMode,
uint32_t requestMode,
uint32_t requestComparisonSelect)
{
PWM->PWM_SCM = channels | updateMode | requestMode
| requestComparisonSelect;
}
/**
* \brief Sets the update period of the synchronous channels.
* This function writes directly to the SCUP register if the channel #0 is disabled;
* otherwise it uses the update register SCUPUPD.
*
* \param period update period.
*/
void PWMC_SetSyncChannelUpdatePeriod(uint8_t period)
{
/* If channel is disabled, write to SCUP */
if ((PWM->PWM_SR & (1 << 0)) == 0) {
PWM->PWM_SCUP = period;
}
/* Otherwise use update register */
else {
PWM->PWM_SCUPUPD = period;
}
}
/**
* \brief Sets synchronous channels update unlock.
*
* Note: If the UPDM field is set to 0, writing the UPDULOCK bit to 1
* triggers the update of the period value, the duty-cycle and
* the dead-time values of synchronous channels at the beginning
* of the next PWM period. If the field UPDM is set to 1 or 2,
* writing the UPDULOCK bit to 1 triggers only the update of
* the period value and of the dead-time values of synchronous channels.
* This bit is automatically reset when the update is done.
*/
void PWMC_SetSyncChannelUpdateUnlock(void)
{
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK;
}
/**
* \brief Enables the given PWM channel.
*
* This does NOT enable the corresponding pin;this must be done in the user code.
*
* \param channel Channel number.
*/
void PWMC_EnableChannel(uint8_t channel)
{
PWM->PWM_ENA = 1 << channel;
}
/**
* \brief Disables the given PWM channel.
*
* Beware, channel will be effectively disabled at the end of the current period.
* Application can check channel is disabled using the following wait loop:
* while ((PWM->PWM_SR & (1 << channel)) != 0);
*
* \param channel Channel number.
*/
void PWMC_DisableChannel(uint8_t channel)
{
PWM->PWM_DIS = 1 << channel;
}
/**
* \brief Enables the period interrupt for the given PWM channel.
*
* \param channel Channel number.
*/
void PWMC_EnableChannelIt(uint8_t channel)
{
PWM->PWM_IER1 = 1 << channel;
}
/**
* \brief Disables the period interrupt for the given PWM channel.
*
* \param channel Channel number.
*/
void PWMC_DisableChannelIt(uint8_t channel)
{
PWM->PWM_IDR1 = 1 << channel;
}
/**
* \brief Enables the selected interrupts sources on a PWMC peripheral.
*
* \param sources1 Bitwise OR of selected interrupt sources of PWM_IER1.
* \param sources2 Bitwise OR of selected interrupt sources of PWM_IER2.
*/
void PWMC_EnableIt(uint32_t sources1, uint32_t sources2)
{
PWM->PWM_IER1 = sources1;
PWM->PWM_IER2 = sources2;
}
/**
* \brief Disables the selected interrupts sources on a PWMC peripheral.
*
* \param sources1 Bitwise OR of selected interrupt sources of PWM_IDR1.
* \param sources2 Bitwise OR of selected interrupt sources of PWM_IDR2.
*/
void PWMC_DisableIt(uint32_t sources1, uint32_t sources2)
{
PWM->PWM_IDR1 = sources1;
PWM->PWM_IDR2 = sources2;
}
/**
* \brief Sends the contents of buffer through a PWMC peripheral, using the PDC to
* take care of the transfer.
*
* Note: Duty cycle of syncronous channels can update by PDC
* when the field UPDM (Update Mode) in the PWM_SCM register is set to 2.
*
* \param pwmc Pointer to an Pwm instance.
* \param buffer Data buffer to send.
* \param length Length of the data buffer.
*/
uint8_t PWMC_WriteBuffer(Pwm *pwmc,
void *buffer,
uint32_t length)
{
/* Check if first bank is free */
if (pwmc->PWM_TCR == 0) {
pwmc->PWM_TPR = (uint32_t) buffer;
pwmc->PWM_TCR = length;
pwmc->PWM_PTCR = PERIPH_PTCR_TXTEN;
return 1;
}
/* Check if second bank is free */
else if (pwmc->PWM_TNCR == 0) {
pwmc->PWM_TNPR = (uint32_t) buffer;
pwmc->PWM_TNCR = length;
return 1;
}
/* No free banks */
return 0;
}
/**
* \brief Set PWM output override value.
*
* \param value Bitwise OR of output override value.
*/
void PWMC_SetOverrideValue(uint32_t value)
{
PWM->PWM_OOV = value;
}
/**
* \brief Enalbe override output.
*
* \param value Bitwise OR of output selection.
* \param sync 0: enable the output asyncronously, 1: enable it syncronously
*/
void PWMC_EnableOverrideOutput(uint32_t value, uint32_t sync)
{
if (sync) {
PWM->PWM_OSSUPD = value;
} else {
PWM->PWM_OSS = value;
}
}
/**
* \brief Disalbe override output.
*
* \param value Bitwise OR of output selection.
* \param sync 0: enable the output asyncronously, 1: enable it syncronously
*/
void PWMC_DisableOverrideOutput(uint32_t value, uint32_t sync)
{
if (sync) {
PWM->PWM_OSCUPD = value;
} else {
PWM->PWM_OSC = value;
}
}
/**
* \brief Set PWM fault mode.
*
* \param mode Bitwise OR of fault mode.
*/
void PWMC_SetFaultMode(uint32_t mode)
{
PWM->PWM_FMR = mode;
}
/**
* \brief PWM fault clear.
*
* \param fault Bitwise OR of fault to clear.
*/
void PWMC_FaultClear(uint32_t fault)
{
PWM->PWM_FCR = fault;
}
/**
* \brief Set PWM fault protection value.
*
* \param value Bitwise OR of fault protection value.
*/
void PWMC_SetFaultProtectionValue(uint32_t value)
{
PWM->PWM_FPV = value;
}
/**
* \brief Enable PWM fault protection.
*
* \param value Bitwise OR of FPEx[y].
*/
void PWMC_EnableFaultProtection(uint32_t value)
{
PWM->PWM_FPE = value;
}
/**
* \brief Configure comparison unit.
*
* \param x comparison x index
* \param value comparison x value.
* \param mode comparison x mode
*/
void PWMC_ConfigureComparisonUnit(uint32_t x, uint32_t value, uint32_t mode)
{
/* If channel is disabled, write to CMPxM & CMPxV */
if ((PWM->PWM_SR & (1 << 0)) == 0) {
if (x == 0) {
PWM->PWM_CMP0M = mode;
PWM->PWM_CMP0V = value;
} else if (x == 1) {
PWM->PWM_CMP1M = mode;
PWM->PWM_CMP1V = value;
} else if (x == 2) {
PWM->PWM_CMP2M = mode;
PWM->PWM_CMP2V = value;
} else if (x == 3) {
PWM->PWM_CMP3M = mode;
PWM->PWM_CMP3V = value;
} else if (x == 4) {
PWM->PWM_CMP4M = mode;
PWM->PWM_CMP4V = value;
} else if (x == 5) {
PWM->PWM_CMP5M = mode;
PWM->PWM_CMP5V = value;
} else if (x == 6) {
PWM->PWM_CMP6M = mode;
PWM->PWM_CMP6V = value;
} else if (x == 7) {
PWM->PWM_CMP7M = mode;
PWM->PWM_CMP7V = value;
}
}
/* Otherwise use update register */
else {
if (x == 0) {
PWM->PWM_CMP0MUPD = mode;
PWM->PWM_CMP0VUPD = value;
} else if (x == 1) {
PWM->PWM_CMP1MUPD = mode;
PWM->PWM_CMP1VUPD = value;
} else if (x == 2) {
PWM->PWM_CMP2MUPD = mode;
PWM->PWM_CMP2VUPD = value;
} else if (x == 3) {
PWM->PWM_CMP3MUPD = mode;
PWM->PWM_CMP3VUPD = value;
} else if (x == 4) {
PWM->PWM_CMP4MUPD = mode;
PWM->PWM_CMP4VUPD = value;
} else if (x == 5) {
PWM->PWM_CMP5MUPD = mode;
PWM->PWM_CMP5VUPD = value;
} else if (x == 6) {
PWM->PWM_CMP6MUPD = mode;
PWM->PWM_CMP6VUPD = value;
} else if (x == 7) {
PWM->PWM_CMP7MUPD = mode;
PWM->PWM_CMP7VUPD = value;
}
}
}
/**
* \brief Configure event line mode.
*
* \param x Line x
* \param mode Bitwise OR of line mode selection
*/
void PWMC_ConfigureEventLineMode(uint32_t x, uint32_t mode)
{
SANITY_CHECK(x < 2);
PWM->PWM_ELxMR[x] = mode;
}
+159
View File
@@ -0,0 +1,159 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* \par Purpose
*
* Interface for configuration the Pulse Width Modulation Controller (PWM) peripheral.
*
* \par Usage
*
* -# Configures PWM clocks A & B to run at the given frequencies using
* \ref PWMC_ConfigureClocks().
* -# Configure PWMC channel using \ref PWMC_ConfigureChannel(), \ref PWMC_ConfigureChannelExt()
* \ref PWMC_SetPeriod(), \ref PWMC_SetDutyCycle() and \ref PWMC_SetDeadTime().
* -# Enable & disable channel using \ref PWMC_EnableChannel() and
* \ref PWMC_DisableChannel().
* -# Enable & disable the period interrupt for the given PWM channel using
* \ref PWMC_EnableChannelIt() and \ref PWMC_DisableChannelIt().
* -# Enable & disable the selected interrupts sources on a PWMC peripheral
* using \ref PWMC_EnableIt() and \ref PWMC_DisableIt().
* -# Control syncronous channel using \ref PWMC_ConfigureSyncChannel(),
* \ref PWMC_SetSyncChannelUpdatePeriod() and \ref PWMC_SetSyncChannelUpdateUnlock().
* -# Control PWM override output using \ref PWMC_SetOverrideValue(),
* \ref PWMC_EnableOverrideOutput() and \ref PWMC_DisableOverrideOutput().
* -# \ref Send data through the transmitter using \ref PWMC_WriteBuffer().
*
*/
#ifndef PWMC_H
#define PWMC_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/* PWM sub-bit field definition. begin */
/* TODO: remove them when AT91SAM3S4.h have the definitions. */
// PWM_CMRx
#define PWM_CMR0_CPRE_MCKA (0xB) // (PWMC_CH)
#define PWM_CMR0_CPRE_MCKB (0xC) // (PWMC_CH)
#define PWM_CMR1_CPRE_MCKA (0xB) // (PWMC_CH)
#define PWM_CMR2_CPRE_MCKA (0xB) // (PWMC_CH)
// PWM_SCM
#define PWM_SCM_UPDM_MODE0 (0x0 << 16) // (PWMC) Manual write of data and manual trigger of the update
#define PWM_SCM_UPDM_MODE1 (0x1 << 16) // (PWMC) Manual write of data and automatic trigger of the update
#define PWM_SCM_UPDM_MODE2 (0x2 << 16) // (PWMC) Automatic write of data and automatic trigger of the update
/* end */
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void PWMC_ConfigureChannel(
uint8_t channel,
uint32_t prescaler,
uint32_t alignment,
uint32_t polarity);
extern void PWMC_ConfigureChannelExt(
uint8_t channel,
uint32_t prescaler,
uint32_t alignment,
uint32_t polarity,
uint32_t countEventSelect,
uint32_t DTEnable,
uint32_t DTHInverte,
uint32_t DTLInverte);
extern void PWMC_ConfigureClocks
(uint32_t clka,
uint32_t clkb,
uint32_t mck);
extern void PWMC_SetPeriod(uint8_t channel, uint16_t period);
extern void PWMC_SetDutyCycle(uint8_t channel, uint16_t duty);
extern void PWMC_SetDeadTime(uint8_t channel, uint16_t timeH, uint16_t timeL);
extern void PWMC_ConfigureSyncChannel(
uint32_t channels,
uint32_t updateMode,
uint32_t requestMode,
uint32_t requestComparisonSelect);
extern void PWMC_SetSyncChannelUpdatePeriod(uint8_t period);
extern void PWMC_SetSyncChannelUpdateUnlock(void);
extern void PWMC_EnableChannel(uint8_t channel);
extern void PWMC_DisableChannel(uint8_t channel);
extern void PWMC_EnableChannelIt(uint8_t channel);
extern void PWMC_DisableChannelIt(uint8_t channel);
extern void PWMC_EnableIt(uint32_t sources1, uint32_t sources2);
extern void PWMC_DisableIt(uint32_t sources1, uint32_t sources2);
extern uint8_t PWMC_WriteBuffer(Pwm *pwmc,
void *buffer,
uint32_t length);
extern void PWMC_SetOverrideValue(uint32_t value);
extern void PWMC_EnableOverrideOutput(uint32_t value, uint32_t sync);
extern void PWMC_DisableOverrideOutput(uint32_t value, uint32_t sync);
extern void PWMC_SetFaultMode(uint32_t mode);
extern void PWMC_FaultClear(uint32_t fault);
extern void PWMC_SetFaultProtectionValue(uint32_t value);
extern void PWMC_EnableFaultProtection(uint32_t value);
extern void PWMC_ConfigureComparisonUnit(uint32_t x, uint32_t value, uint32_t mode);
extern void PWMC_ConfigureEventLineMode(uint32_t x, uint32_t mode);
#endif /* #ifndef PWMC_H */
@@ -0,0 +1,6 @@
QTouch library for AT91SAM3S-EK board version A.
Modified board.
Burst pulses 5 CPU cycles wide.
Slider on pins PA0, PA1, PA2, PA3, PA4, PA5
@@ -0,0 +1,10 @@
QTouch library for AT91SAM3S-EK board version A.
Modified board.
Burst pulses 5 CPU cycles wide.
A Valid key on pins PC22 and PC23
A UP key on pins PC24 and PC25
A Down key on pins PC26 and PC27
A Left key on pins PC28 and PC29
A right key on pins PC30 and PC31
@@ -0,0 +1,11 @@
QTouch library for AT91SAM3S-EK board version B.
Burst pulses 5 CPU cycles wide.
Slider on pins PA0, PA1, PA2, PA3, PA4, PA5
A Valid key on pins PC22 and PC23
A UP key on pins PC24 and PC25
A Down key on pins PC26 and PC27
A Left key on pins PC28 and PC29
A right key on pins PC30 and PC31
+467
View File
@@ -0,0 +1,467 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup rtc_module Working with RTC
* The RTC driver provides the interface to configure and use the RTC
* peripheral.
*
* It manages date, time, and alarms.\n
* This timer is clocked by the 32kHz system clock, and is not impacted by
* power management settings (PMC). To be accurate, it is better to use an
* external 32kHz crystal instead of the internal 32kHz RC.\n
*
* It uses BCD format, and time can be set in AM/PM or 24h mode through a
* configuration bit in the mode register.\n
*
* To update date or time, the user has to follow these few steps :
* <ul>
* <li>Set UPDTIM and/or UPDCAL bit(s) in RTC_CR,</li>
* <li>Polling or IRQ on the ACKUPD bit of RTC_CR,</li>
* <li>Clear ACKUPD bit in RTC_SCCR,</li>
* <li>Update Time and/or Calendar values in RTC_TIMR/RTC_CALR (BCD format),</li>
* <li>Clear UPDTIM and/or UPDCAL bit in RTC_CR.</li>
* </ul>
* An alarm can be set to happen on month, date, hours, minutes or seconds,
* by setting the proper "Enable" bit of each of these fields in the Time and
* Calendar registers.
* This allows a large number of configurations to be available for the user.
* Alarm occurence can be detected even by polling or interrupt.
*
* A check of the validity of the date and time format and values written by the user is automatically done.
* Errors are reported through the Valid Entry Register.
*
* For more accurate information, please look at the RTC section of the
* Datasheet.
*
* Related files :\n
* \ref rtc.c\n
* \ref rtc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Real Time Clock (RTC) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
/* These headers were introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */
#include <stdint.h>
#include "rtc.h"
#include <board.h>
#include <utility/assert.h>
#include <utility/trace.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Sets the RTC in either 12 or 24 hour mode.
*
* \param mode Hour mode.
*/
void RTC_SetHourMode(uint32_t mode)
{
SANITY_CHECK((mode & 0xFFFFFFFE) == 0);
TRACE_DEBUG("RTC_SetHourMode()\n\r");
RTC->RTC_MR = mode;
}
/**
* \brief Gets the RTC mode.
*
* \return Hour mode.
*/
uint32_t RTC_GetHourMode( void )
{
uint32_t hmode;
TRACE_DEBUG("RTC_SetHourMode()\n\r");
hmode = RTC->RTC_MR;
hmode &= 0xFFFFFFFE;
return hmode;
}
/**
* \brief Enables the selected interrupt sources of the RTC.
*
* \param sources Interrupt sources to enable.
*/
void RTC_EnableIt(uint32_t sources)
{
SANITY_CHECK((sources & ~0x1F) == 0);
TRACE_DEBUG("RTC_EnableIt()\n\r");
RTC->RTC_IER = sources;
}
/**
* \brief Disables the selected interrupt sources of the RTC.
*
* \param sources Interrupt sources to disable.
*/
void RTC_DisableIt(uint32_t sources)
{
SANITY_CHECK((sources & ~0x1F) == 0);
TRACE_DEBUG("RTC_DisableIt()\n\r");
RTC->RTC_IDR = sources;
}
/**
* \brief Sets the current time in the RTC.
*
* \param hour Current hour in 12 or 24 hour mode.
* \param minute Current minute.
* \param second Current second.
* \return 0 sucess, 1 fail to set
*/
int RTC_SetTime(uint8_t hour, uint8_t minute, uint8_t second)
{
uint32_t time=0;
uint8_t hour_bcd;
uint8_t min_bcd;
uint8_t sec_bcd;
TRACE_DEBUG("RTC_SetTime(%02d:%02d:%02d)\n\r", hour, minute, second);
/* if 12-hour mode, set AMPM bit */
if ((RTC->RTC_MR & RTC_MR_HRMOD) == RTC_MR_HRMOD) {
if (hour > 12) {
hour -= 12;
time |= RTC_TIMR_AMPM;
}
}
hour_bcd = (hour%10) | ((hour/10)<<4);
min_bcd = (minute%10) | ((minute/10)<<4);
sec_bcd = (second%10) | ((second/10)<<4);
/* value overflow */
if((hour_bcd & (uint8_t)(~RTC_HOUR_BIT_LEN_MASK)) |
(min_bcd & (uint8_t)(~RTC_MIN_BIT_LEN_MASK)) |
(sec_bcd & (uint8_t)(~RTC_SEC_BIT_LEN_MASK)))
return 1;
time = sec_bcd | (min_bcd << 8) | (hour_bcd<<16);
/* Set time */
while ((RTC->RTC_SR & RTC_SR_SEC) != RTC_SR_SEC); /* wait from previous set */
RTC->RTC_CR |= RTC_CR_UPDTIM;
while ((RTC->RTC_SR & RTC_SR_ACKUPD) != RTC_SR_ACKUPD);
RTC->RTC_SCCR = RTC_SCCR_ACKCLR;
RTC->RTC_TIMR = time;
RTC->RTC_CR &= ~RTC_CR_UPDTIM;
RTC->RTC_SCCR |= RTC_SCCR_SECCLR; /* clear SECENV in SCCR */
return (int)(RTC->RTC_VER & RTC_VER_NVTIM);
}
/**
* \brief Retrieves the current time as stored in the RTC in several variables.
*
* \param pHour If not null, current hour is stored in this variable.
* \param pMinute If not null, current minute is stored in this variable.
* \param pSecond If not null, current second is stored in this variable.
*/
void RTC_GetTime(
uint8_t *pHour,
uint8_t *pMinute,
uint8_t *pSecond)
{
uint32_t time;
TRACE_DEBUG("RTC_GetTime()\n\r");
/* Get current RTC time */
time = RTC->RTC_TIMR;
while (time != RTC->RTC_TIMR) {
time = RTC->RTC_TIMR;
}
/* Hour */
if (pHour) {
*pHour = ((time & 0x00300000) >> 20) * 10
+ ((time & 0x000F0000) >> 16);
if ((time & RTC_TIMR_AMPM) == RTC_TIMR_AMPM) {
*pHour += 12;
}
}
/* Minute */
if (pMinute) {
*pMinute = ((time & 0x00007000) >> 12) * 10
+ ((time & 0x00000F00) >> 8);
}
/* Second */
if (pSecond) {
*pSecond = ((time & 0x00000070) >> 4) * 10
+ (time & 0x0000000F);
}
}
/**
* \brief Sets a time alarm on the RTC.
* The match is performed only on the provided variables;
* Setting all pointers to 0 disables the time alarm.
*
* \note In AM/PM mode, the hour value must have bit #7 set for PM, cleared for
* AM (as expected in the time registers).
*
* \param pHour If not null, the time alarm will hour-match this value.
* \param pMinute If not null, the time alarm will minute-match this value.
* \param pSecond If not null, the time alarm will second-match this value.
* \return 0 success, 1 fail to set
*/
int RTC_SetTimeAlarm(
uint8_t *pHour,
uint8_t *pMinute,
uint8_t *pSecond)
{
uint32_t alarm = 0;
TRACE_DEBUG("RTC_SetTimeAlarm()\n\r");
/* Hour */
if (pHour) {
alarm |= RTC_TIMALR_HOUREN | ((*pHour / 10) << 20) | ((*pHour % 10) << 16);
}
/* Minute */
if (pMinute) {
alarm |= RTC_TIMALR_MINEN | ((*pMinute / 10) << 12) | ((*pMinute % 10) << 8);
}
/* Second */
if (pSecond) {
alarm |= RTC_TIMALR_SECEN | ((*pSecond / 10) << 4) | (*pSecond % 10);
}
RTC->RTC_TIMALR = alarm;
return (int)(RTC->RTC_VER & RTC_VER_NVTIMALR);
}
/**
* \brief Retrieves the current year, month and day from the RTC.
* Month, day and week values are numbered starting at 1.
*
* \param pYear Current year (optional).
* \param pMonth Current month (optional).
* \param pDay Current day (optional).
* \param pWeek Current day in current week (optional).
*/
void RTC_GetDate(
unsigned short *pYear,
uint8_t *pMonth,
uint8_t *pDay,
uint8_t *pWeek)
{
uint32_t date;
/* Get current date (multiple reads are necessary to insure a stable value) */
do {
date = RTC->RTC_CALR;
}
while (date != RTC->RTC_CALR);
/* Retrieve year */
if (pYear) {
*pYear = (((date >> 4) & 0x7) * 1000)
+ ((date & 0xF) * 100)
+ (((date >> 12) & 0xF) * 10)
+ ((date >> 8) & 0xF);
}
/* Retrieve month */
if (pMonth) {
*pMonth = (((date >> 20) & 1) * 10) + ((date >> 16) & 0xF);
}
/* Retrieve day */
if (pDay) {
*pDay = (((date >> 28) & 0x3) * 10) + ((date >> 24) & 0xF);
}
/* Retrieve week */
if (pWeek) {
*pWeek = ((date >> 21) & 0x7);
}
}
/**
* \brief Sets the current year, month and day in the RTC.
* Month, day and week values must be numbered starting from 1.
*
* \param year Current year.
* \param month Current month.
* \param day Current day.
* \param week Day number in current week.
* \return 0 success, 1 fail to set
*/
int RTC_SetDate(
unsigned short year,
uint8_t month,
uint8_t day,
uint8_t week)
{
uint32_t date;
uint8_t cent_bcd;
uint8_t year_bcd;
uint8_t month_bcd;
uint8_t day_bcd;
uint8_t week_bcd;
cent_bcd = ((year/100)%10) | ((year/1000)<<4);
year_bcd = (year%10) | (((year/10)%10)<<4);
month_bcd = ((month%10) | (month/10)<<4);
day_bcd = ((day%10) | (day/10)<<4);
week_bcd = ((week%10) | (week/10)<<4);
/* value over flow */
if((cent_bcd & (uint8_t)(~RTC_CENT_BIT_LEN_MASK)) |
(year_bcd & (uint8_t)(~RTC_YEAR_BIT_LEN_MASK)) |
(month_bcd & (uint8_t)(~RTC_MONTH_BIT_LEN_MASK)) |
(week_bcd & (uint8_t)(~RTC_WEEK_BIT_LEN_MASK)) |
(day_bcd & (uint8_t)(~RTC_DATE_BIT_LEN_MASK)))
return 1;
/* Convert values to date register value */
date = cent_bcd |
(year_bcd << 8) |
(month_bcd << 16) |
(week_bcd << 21) |
(day_bcd << 24);
/* Update calendar register */
while ((RTC->RTC_SR & RTC_SR_SEC) != RTC_SR_SEC); /* wait from previous set */
RTC->RTC_CR |= RTC_CR_UPDCAL;
while ((RTC->RTC_SR & RTC_SR_ACKUPD) != RTC_SR_ACKUPD);
RTC->RTC_SCCR = RTC_SCCR_ACKCLR;
RTC->RTC_CALR = date;
RTC->RTC_CR &= ~RTC_CR_UPDCAL;
RTC->RTC_SCCR |= RTC_SCCR_SECCLR; /* clear SECENV in SCCR */
return (int)(RTC->RTC_VER & RTC_VER_NVCAL);
}
/**
* \brief Sets a date alarm in the RTC.
* The alarm will match only the provided values;
* Passing a null-pointer disables the corresponding field match.
*
* \param pMonth If not null, the RTC alarm will month-match this value.
* \param pDay If not null, the RTC alarm will day-match this value.
* \return 0 success, 1 fail to set
*/
int RTC_SetDateAlarm(uint8_t *pMonth, uint8_t *pDay)
{
uint32_t alarm;
alarm = ((pMonth) || (pDay)) ? (0) : (0x01010000);
TRACE_DEBUG("RTC_SetDateAlarm()\n\r");
/* Compute alarm field value */
if (pMonth) {
alarm |= RTC_CALALR_MTHEN | ((*pMonth / 10) << 20) | ((*pMonth % 10) << 16);
}
if (pDay) {
alarm |= RTC_CALALR_DATEEN | ((*pDay / 10) << 28) | ((*pDay % 10) << 24);
}
/* Set alarm */
RTC->RTC_CALALR = alarm;
return (int)(RTC->RTC_VER & RTC_VER_NVCALALR);
}
/**
* \brief Clear flag bits of status clear command register in the RTC.
*
* \param mask Bits mask of cleared events
*/
void RTC_ClearSCCR(uint32_t mask)
{
/* Clear all flag bits in status clear command register */
mask &= RTC_SCCR_ACKCLR | RTC_SCCR_ALRCLR | RTC_SCCR_SECCLR | \
RTC_SCCR_TIMCLR | RTC_SCCR_CALCLR;
RTC->RTC_SCCR = mask;
}
/**
* \brief Get flag bits of status register in the RTC.
*
* \param mask Bits mask of Status Register
* \return Status register & mask
*/
uint32_t RTC_GetSR(uint32_t mask)
{
uint32_t event;
event = RTC->RTC_SR;
return (event & mask);
}
+99
View File
@@ -0,0 +1,99 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for Real Time Clock (RTC) controller.
*
*/
#ifndef RTC_H
#define RTC_H
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#define RTC_HOUR_BIT_LEN_MASK 0x3F
#define RTC_MIN_BIT_LEN_MASK 0x7F
#define RTC_SEC_BIT_LEN_MASK 0x7F
#define RTC_CENT_BIT_LEN_MASK 0x7F
#define RTC_YEAR_BIT_LEN_MASK 0xFF
#define RTC_MONTH_BIT_LEN_MASK 0x1F
#define RTC_DATE_BIT_LEN_MASK 0x3F
#define RTC_WEEK_BIT_LEN_MASK 0x07
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void RTC_SetHourMode(uint32_t mode);
extern uint32_t RTC_GetHourMode( void ) ;
extern void RTC_EnableIt(uint32_t sources);
extern void RTC_DisableIt(uint32_t sources);
extern int RTC_SetTime(
uint8_t hour,
uint8_t minute,
uint8_t second);
extern void RTC_GetTime(
uint8_t *pHour,
uint8_t *pMinute,
uint8_t *pSecond);
extern int RTC_SetTimeAlarm(
uint8_t *pHour,
uint8_t *pMinute,
uint8_t *pSecond);
extern void RTC_GetDate(
unsigned short *pYear,
uint8_t *pMonth,
uint8_t *pDay,
uint8_t *pWeek);
extern int RTC_SetDate(
unsigned short year,
uint8_t month,
uint8_t day,
uint8_t week);
extern int RTC_SetDateAlarm(uint8_t *pMonth, uint8_t *pDay);
extern void RTC_ClearSCCR(uint32_t mask);
extern uint32_t RTC_GetSR(uint32_t mask);
#endif /* #ifndef RTC_H */
+136
View File
@@ -0,0 +1,136 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup rtt_module Working with RTT
* The RTT driver provides the interface to configure and use the RTT
* peripheral.
*
* The Real-time Timer is used to count elapsed seconds.\n
* This timer is clocked by the 32kHz system clock divided by a programmable
* 16-bit balue. To be accurate, it is better to use an
* external 32kHz crystal instead of the internal 32kHz RC.\n
*
* To count elapsed seconds, the user could follow these few steps:
* <ul>
* <li>Programming PTPRES in RTT_MR to feeding the timer with a 1Hz signal.</li>
* <li>Writing the bit RTTRST in RTT_MR to restart the timer with new settings.</li>
* </ul>
*
* An alarm can be set to happen on second by setting alarm value in RTT_AR.
* Alarm occurence can be detected by polling or interrupt.
*
* For more accurate information, please look at the RTT section of the
* Datasheet.
*
* Related files :\n
* \ref rtt.c\n
* \ref rtt.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Real Time Timer (RTT) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
/* These headers were introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */
#include <stdint.h>
#include "rtt.h"
#include <utility/assert.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Changes the prescaler value of the given RTT and restarts it.
*
* \note This function disables RTT interrupt sources.
*
* \param rtt Pointer to a Rtt instance.
* \param prescaler Prescaler value for the RTT.
*/
void RTT_SetPrescaler(Rtt *rtt, uint16_t prescaler)
{
rtt->RTT_MR = (prescaler | RTT_MR_RTTRST);
}
/**
* \brief Returns the current value of the RTT timer value.
*
* \param rtt Pointer to a Rtt instance.
*/
uint32_t RTT_GetTime(Rtt *rtt)
{
return rtt->RTT_VR;
}
/**
* \brief Enables the specified RTT interrupt sources.
*
* \param rtt Pointer to a Rtt instance.
* \param sources Bitmask of interrupts to enable.
*/
void RTT_EnableIT(Rtt *rtt, uint32_t sources)
{
ASSERT((sources & 0x0004FFFF) == 0,
"RTT_EnableIT: Wrong sources value.\n\r");
rtt->RTT_MR |= sources;
}
/**
* \brief Returns the status register value of the given RTT.
*
* \param rtt Pointer to an Rtt instance.
*/
uint32_t RTT_GetStatus(Rtt *rtt)
{
return rtt->RTT_SR;
}
/**
* \brief Configures the RTT to generate an alarm at the given time.
*
* \param pRtt Pointer to an Rtt instance.
* \param time Alarm time.
*/
void RTT_SetAlarm(Rtt *pRtt, uint32_t time)
{
SANITY_CHECK(time > 0);
pRtt->RTT_AR = time - 1;
}
+80
View File
@@ -0,0 +1,80 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* \par Purpose
*
* Interface for Real Time Timer (RTT) controller.
*
* \par Usage
*
* -# Changes the prescaler value of the given RTT and restarts it
* using \ref RTT_SetPrescaler().
* -# Get current value of the RTT using \ref RTT_GetTime().
* -# Enables the specified RTT interrupt using \ref RTT_EnableIT().
* -# Get the status register value of the given RTT using \ref RTT_GetStatus().
* -# Configures the RTT to generate an alarm at the given time
* using \ref RTT_SetAlarm().
*/
#ifndef RTT_H
#define RTT_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#ifndef AT91C_BASE_RTTC
#define AT91C_BASE_RTTC RTT
#endif
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void RTT_SetPrescaler(Rtt *rtt, uint16_t prescaler);
extern uint32_t RTT_GetTime(Rtt *rtt);
extern void RTT_EnableIT(Rtt *rtt, uint32_t sources);
extern uint32_t RTT_GetStatus(Rtt *rtt);
extern void RTT_SetAlarm(Rtt *pRtt, uint32_t time);
#endif /* #ifndef RTT_H */
@@ -0,0 +1,253 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup at45d_module AT45 driver.
* The AT45 Dataflash driver is based on the corresponding AT45 driver.
* A AT45 instance has to be initialized using the Dataflash levle function
* AT45_Configure(). AT45 Dataflash can be automatically detected using
* the AT45_FindDevice() function. Then AT45 dataflash operations such as
* read, write and erase DF can be launched using AT45_SendCommand function
* with corresponding AT45 command set.
*
* \usage
* <ul>
* <li> Reads data from the At45 at the specified address using AT45D_Read().</li>
* <li> Writes data on the At45 at the specified address using AT45D_Write().</li>
* <li> Erases a page of data at the given address using AT45D_Erase().</li>
* <li> Poll until the At45 has completed of corresponding operations using
* AT45D_WaitReady().</li>
* <li> Retrieves and returns the At45 current using AT45D_GetStatus().</li>
* </ul>
* Related files :\n
* \ref at45d.c\n
* \ref at45d.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of At45 driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "spi_at45.h"
#include "at45d.h"
#include <board.h>
#include <utility/assert.h>
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Wait for transfer to finish calling the SPI driver ISR (interrupts are
* disabled).
*
* \param pAt45 Pointer to an AT45 driver instance.
*/
static void AT45D_Wait(At45 *pAt45)
{
SANITY_CHECK(pAt45);
/* Wait for transfer to finish*/
while (AT45_IsBusy(pAt45)) {
SPID_Handler(pAt45->pSpid);
}
}
/*----------------------------------------------------------------------------
* Global functions
*----------------------------------------------------------------------------*/
/**
* \brief Waits for the At45 to be ready to accept new commands.
*
* \param pAt45 Pointer to an AT45 driver instance.
*/
void AT45D_WaitReady(At45 *pAt45)
{
uint8_t ready = 0;
SANITY_CHECK(pAt45);
/* Poll device until it is ready.*/
while (!ready) {
ready = AT45_STATUS_READY(AT45D_GetStatus(pAt45));
}
}
/**
* \brief Retrieves and returns the At45 current status, or 0 if an error happened.
*
* \param pAt45 Pointer to an AT45 driver instance.
*/
uint8_t AT45D_GetStatus(At45 *pAt45)
{
uint8_t error;
uint8_t status;
SANITY_CHECK(pAt45);
/* Issue a status register read command*/
error = AT45_SendCommand(pAt45, AT45_STATUS_READ, 1, &status, 1, 0, 0, 0);
ASSERT(!error, "-F- AT45_GetStatus: Failed to issue command.\n\r");
/* Wait for command to terminate*/
while (AT45_IsBusy(pAt45)) {
AT45D_Wait(pAt45);
}
return status;
}
/**
* \brief Reads data from the At45 inside the provided buffer. Since a continuous
* read command is used, there is no restriction on the buffer size and read address.
*
* \param pAt45 Pointer to an AT45 driver instance.
* \param pBuffer Data buffer.
* \param size Number of bytes to read.
* \param address Address at which data shall be read.
*/
void AT45D_Read(
At45 *pAt45,
uint8_t *pBuffer,
uint32_t size,
uint32_t address)
{
uint8_t error;
SANITY_CHECK(pAt45);
SANITY_CHECK(pBuffer);
/* Issue a continuous read array command.*/
error = AT45_SendCommand(pAt45, AT45_CONTINUOUS_READ_LEG, 8, pBuffer, size, address, 0, 0);
ASSERT(!error, "-F- AT45_Read: Failed to issue command\n\r");
/* Wait for the read command to execute.*/
while (AT45_IsBusy(pAt45)) {
AT45D_Wait(pAt45);
}
}
/**
* \brief Writes data on the At45 at the specified address. Only one page of
* data is written that way; if the address is not at the beginning of the
* page, the data is written starting from this address and wraps around to
* the beginning of the page.
* \param pAt45 Pointer to an AT45 driver instance.
* \param pBuffer Data buffer.
* \param size Number of bytes to write.
* \param address Destination address on the At45.
*/
void AT45D_Write(
At45 *pAt45,
uint8_t *pBuffer,
uint32_t size,
uint32_t address)
{
uint8_t error;
SANITY_CHECK(pAt45);
SANITY_CHECK(pBuffer);
SANITY_CHECK(size <= pAt45->pDesc->pageSize);
/* Issue a page write through buffer 1 command. */
error = AT45_SendCommand(pAt45, AT45_PAGE_WRITE_BUF1, 4, pBuffer, size, address, 0, 0);
ASSERT(!error, "-F- AT45_Write: Could not issue command.\n\r");
/* Wait until the command is sent. */
while (AT45_IsBusy(pAt45)) {
AT45D_Wait(pAt45);
}
/* Wait until the At45 becomes ready again.*/
AT45D_WaitReady(pAt45);
}
/**
* \brief Erases a page of data at the given address in the At45.
*
* \param pAt45 Pointer to an AT45 driver instance.
* \param address Address of page to erase.
*/
void AT45D_Erase(At45 *pAt45, uint32_t address)
{
uint8_t error;
SANITY_CHECK(pAt45);
/* Issue a page erase command. */
error = AT45_SendCommand(pAt45, AT45_PAGE_ERASE, 4, 0, 0, address, 0, 0);
ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");
/* Wait for end of transfer. */
while (AT45_IsBusy(pAt45)) {
AT45D_Wait(pAt45);
}
/* Poll until the At45 has completed the erase operation.*/
AT45D_WaitReady(pAt45);
}
/**
* \brief Configure power-of-2 binary page size in the At45.
*
* \param pAt45 Pointer to an AT45 driver instance.
*/
void AT45D_BinaryPage(At45 *pAt45)
{
uint8_t error;
uint8_t opcode[3]= {AT45_BINARY_PAGE};
SANITY_CHECK(pAt45);
/* Issue a binary page command. */
error = AT45_SendCommand(pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0);
ASSERT(!error, "-F- AT45_Erase: Could not issue command.\n\r");
/* Wait for end of transfer.*/
while (AT45_IsBusy(pAt45)) {
AT45D_Wait(pAt45);
}
/* Wait until the At45 becomes ready again.*/
AT45D_WaitReady(pAt45);
}
@@ -0,0 +1,72 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of At45 driver.
*
*/
#ifndef AT45D_H
#define AT45D_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "spi_at45.h"
/*----------------------------------------------------------------------------
* Global functions
*----------------------------------------------------------------------------*/
extern void AT45D_WaitReady(At45 *pAt45);
extern uint8_t AT45D_GetStatus(At45 *pAt45);
extern void AT45D_Read(
At45 *pAt45,
uint8_t *pBuffer,
uint32_t size,
uint32_t address);
extern void AT45D_Write(
At45 *pAt45,
uint8_t *pBuffer,
uint32_t size,
uint32_t address);
extern void AT45D_Erase(At45 *pAt45, uint32_t address);
extern void AT45D_BinaryPage(At45 *pAt45);
#endif //#ifndef AT45D_H
@@ -0,0 +1,311 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup spi_at45_module SPI AT45 driver.
* The Dataflash driver is based on top of the corresponding Spi driver.
* A Dataflash structure instance has to be initialized using the DF_Init
* function. Then basic dataflash operations can be launched using macros such
* as DF_continuous_read. These macros invoke the DF_Command() function which
* invokes the DPI low driver using the SPI_SendCommand() function.
* Beware to compute the dataflash internal address, the dataflash sector
* description must be known (DataflashDesc). Dataflash can be automatically
* detected using the DF_Scan() function.
*
* \usage
* <ul>
* <li> Initializes an AT45 instance and configures SPI chip select pin
* using AT45_Configure(). </li>
* <li> Detect DF and returns DF description corresponding to the device
* connected using AT45_FindDevice().This function shall be called by
* the application before AT45_SendCommand.</li>
* <li>Sends a command to the DF through the SPI using AT45_SendCommand().
* The command is identified by its command code and the number of
* bytes to transfer.</li>
* <li>Example code for sending command to write a page to DF. </li>
* \code
* // Issue a page write through buffer 1 command
* error = AT45_SendCommand(pAt45, AT45_PAGE_WRITE_BUF1, 4,
* pBuffer, size, address, 0, 0);
* \endcode
* <li>Example code for sending command to read a page from DF.
* If data needs to be received, then a data buffer must be
* provided.</li>
* \code
* // Issue a continuous read array command
* error = AT45_SendCommand(pAt45, AT45_CONTINUOUS_READ_LEG, 8,
* pBuffer, size, address, 0, 0);
* \endcode
* <li> This function does not block; its optional callback will
* be invoked when the transfer completes.</li>
* <li> Check the AT45 driver is ready or not by polling AT45_IsBusy().
* </ul>
* Related files :\n
* \ref spi_at45.c\n
* \ref spi_at45.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of SPI At45 driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "spi_at45.h"
#include <board.h>
#include <utility/assert.h>
#include <string.h>
/*----------------------------------------------------------------------------
* Internal definitions
*----------------------------------------------------------------------------*/
/** Number of dataflash which can be recognized.*/
#define NUMDATAFLASH (sizeof(at45Devices) / sizeof(At45Desc))
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** indicate if the device is configured as binary page or not.*/
static uint8_t configuredBinaryPage;
/** At45 device descriptor structure. */
static const At45Desc at45Devices[] = {
{ 512, 1, 264, 9, 0x0C, "AT45DB011D"},
{ 1024, 1, 264, 9, 0x14, "AT45DB021D"},
{ 2048, 1, 264, 9, 0x1C, "AT45DB041D"},
{ 4096, 1, 264, 9, 0x24, "AT45DB081D"},
{ 4096, 1, 528, 10, 0x2C, "AT45DB161D"},
{ 8192, 1, 528, 10, 0x34, "AT45DB321D"},
{ 8192, 1, 1056, 11, 0x3C, "AT45DB642D"},
{16384, 1, 1056, 11, 0x10, "AT45DB1282"},
{16384, 1, 2112, 12, 0x18, "AT45DB2562"},
{32768, 1, 2112, 12, 0x20, "AT45DB5122"}
};
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initializes an AT45 instance and configures SPI chip select register.
*
* \param pAt45 Pointer to the At45 instance to initialize.
* \param pSpid Pointer to the underlying SPI driver.
* \param spiCs Chip select value to connect to the At45.
* \return 0.
*/
uint8_t AT45_Configure(At45 *pAt45, Spid *pSpid, uint8_t spiCs)
{
SpidCmd *pCommand;
/* Sanity checks */
ASSERT(pSpid, "AT45_Configure: pSpid is 0.\n\r");
ASSERT(pAt45, "AT45_Configure: pAt45 is 0.\n\r");
/* Initialize the At45 instance */
pAt45->pSpid = pSpid;
pAt45->pDesc = 0;
memset(pAt45->pCmdBuffer, 0, 8);
/* Initialize the spidCmd structure*/
pCommand = &(pAt45->command);
pCommand->pCmd = pAt45->pCmdBuffer;
pCommand->callback = 0;
pCommand->pArgument = 0;
pCommand->spiCs = spiCs;
return 0;
}
/**
* \brief Check if the At45 driver is in busy.
*
* \param pAt45 Pointer to the At45 instance to initialize.
* \return 1 if the At45 driver is not executing any command,otherwise it returns 0.
*/
uint8_t AT45_IsBusy(At45 *pAt45)
{
return SPID_IsBusy(pAt45->pSpid);
}
/**
* \brief Sends a command to the dataflash through the SPI.
* The command is identified by its command code and the number of bytes to transfer
* (1 + number of address bytes + number of dummy bytes).If data needs to be received,
* then a data buffer must be provided.
* \note This function does not block; its optional callback will be invoked when
* the transfer completes.
* \param pAt45 Pointer to the At45 instance to initialize.
* \param cmd Command code.
* \param cmdSize Size of command code + address bytes + dummy bytes.
* \param pData Data buffer.
* \param dataSize Number of data bytes to send/receive.
* \param address Address at which the command is performed if meaningful.
* \param callback Optional callback to invoke at end of transfer.
* \param pArgument Optional parameter to the callback function.
* \return 0.
*/
uint8_t AT45_SendCommand(
At45 *pAt45,
uint8_t cmd,
uint8_t cmdSize,
uint8_t *pData,
uint32_t dataSize,
uint32_t address,
SpidCallback callback,
void *pArgument)
{
SpidCmd *pCommand;
const At45Desc *pDesc = pAt45->pDesc;
uint32_t dfAddress = 0;
/* Sanity checks*/
ASSERT(pAt45, "AT45_Command: pAt45 is 0.\n\r");
ASSERT(pDesc || (cmd == AT45_STATUS_READ),
"AT45_Command: Device has no descriptor, only STATUS_READ command allowed\n\r");
/* Check if the SPI driver is available*/
if (AT45_IsBusy(pAt45)) {
return AT45_ERROR_LOCK;
}
/* Compute command pattern*/
pAt45->pCmdBuffer[0] = cmd;
/* Add address bytes if necessary*/
if (cmdSize > 1) {
ASSERT(pDesc, "AT45_Command: No descriptor for dataflash.\n\r");
if (!configuredBinaryPage) {
dfAddress =
((address / (pDesc->pageSize)) << pDesc->pageOffset)
+ (address % (pDesc->pageSize));
}
else {
dfAddress = address;
}
/* Write address bytes*/
if (pDesc->pageNumber >= 16384) {
pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);
if ((cmd != AT45_CONTINUOUS_READ) && (cmd != AT45_PAGE_READ)) {
cmdSize++;
}
}
else {
pAt45->pCmdBuffer[1] = ((dfAddress & 0x00FF0000) >> 16);
pAt45->pCmdBuffer[2] = ((dfAddress & 0x0000FF00) >> 8);
pAt45->pCmdBuffer[3] = ((dfAddress & 0x000000FF) >> 0);
}
}
/* Update the SPI Transfer descriptors*/
pCommand = &(pAt45->command);
pCommand->cmdSize = cmdSize;
pCommand->pData = pData;
pCommand->dataSize = dataSize;
pCommand->callback = callback;
pCommand->pArgument = pArgument;
/* Send Command and data through the SPI*/
if (SPID_SendCommand(pAt45->pSpid, pCommand)) {
return AT45_ERROR_SPI;
}
return 0;
}
/**
* \brief returns the At45Desc structure corresponding to the device connected.
* It automatically initializes pAt45->pDesc field structure.
* \note This function shall be called by the application before AT45_SendCommand.
* \param pAt45 Pointer to the At45 instance to initialize.
* \param status Device status register value.
* \return 0 if successful; Otherwise, returns AT45_ERROR_LOCK if the At45
* driver is in use or AT45_ERROR_SPI if there was an error with the SPI driver.
*/
const At45Desc * AT45_FindDevice(At45 *pAt45, uint8_t status)
{
uint32_t i;
uint8_t id = AT45_STATUS_ID(status);
/* Check if status is all one; in which case, it is assumed that no device is connected*/
if (status == 0xFF) {
return 0;
}
/* Look in device array */
i = 0;
pAt45->pDesc = 0;
while ((i < NUMDATAFLASH) && !(pAt45->pDesc)) {
if (at45Devices[i].id == id) {
pAt45->pDesc = &(at45Devices[i]);
}
i++;
}
configuredBinaryPage = AT45_STATUS_BINARY(status);
return pAt45->pDesc;
}
/**
* \brief returns the pagesize corresponding to the device connected.
* \param pAt45 Pointer to the At45 instance to initialize.
* \param status Device status register value.
* \return page size.
*/
uint32_t AT45_PageSize(At45 *pAt45)
{
uint32_t pagesize = pAt45->pDesc->pageSize;
if(((pAt45->pDesc->hasBinaryPage) == 0) || !configuredBinaryPage){
return pagesize;
}
return ((pagesize >> 8) << 8);
}
@@ -0,0 +1,202 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of SPI At45 driver.
*
*/
#ifndef SPI_AT45_H
#define SPI_AT45_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "spi_pdc.h"
/*----------------------------------------------------------------------------
* Macros
*----------------------------------------------------------------------------*/
/** Returns 1 if the device is ready; otherwise 0.*/
#define AT45_STATUS_READY(status) (status & 0x80)
/** Returns the device ID code.*/
#define AT45_STATUS_ID(status) (status & 0x3c)
/** Returns 1 if the device is configured in binary page mode; otherwise 0.*/
#define AT45_STATUS_BINARY(status) (status & 0x01)
#define AT45_PageOffset(pAt45) ((pAt45)->pDesc->pageOffset)
#define AT45_PageNumber(pAt45) ((pAt45)->pDesc->pageNumber)
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** The dataflash driver is currently in use.*/
#define AT45_ERROR_LOCK 1
/** There was an error with the SPI driver.*/
#define AT45_ERROR_SPI 2
/** AT45 dataflash SPI CSR settings given MCK and SPCK.*/
#define AT45_CSR(mck, spck) (SPI_CSR_NCPHA | SPID_CSR_DLYBCT(mck, 250) | SPID_CSR_DLYBS(mck, 250) | SPID_CSR_SCBR(mck, spck))
/** Main memory page read command code. */
#define AT45_PAGE_READ 0xD2
/** Continous array read (legacy) command code.*/
#define AT45_CONTINUOUS_READ_LEG 0xE8
/** Continous array read (low frequency) command code.*/
#define AT45_CONTINUOUS_READ_LF 0x03
/** Continous array read command code.*/
#define AT45_CONTINUOUS_READ 0x0B
/** Buffer 1 read (low frequency) command code.*/
#define AT45_BUF1_READ_LF 0xD1
/** Buffer 2 read (low frequency) command code.*/
#define AT45_BUF2_READ_LF 0xD3
/** Buffer 1 read (serial) command code.*/
#define AT45_BUF1_READ_SER 0xD4
/** Buffer 2 read (serial) command code.*/
#define AT45_BUF2_READ_SER 0xD6
/** Buffer 1 read (8-bit) command code.*/
#define AT45_BUF1_READ_8B 0x54
/** Buffer 2 read (8-bit) command code.*/
#define AT45_BUF2_READ_8B 0x56
/** Buffer 1 write command code.*/
#define AT45_BUF1_WRITE 0x84
/** Buffer 2 write command code.*/
#define AT45_BUF2_WRITE 0x87
/** Buffer 1 to main memory page program with erase command code.*/
#define AT45_BUF1_MEM_ERASE 0x83
/** Buffer 2 to main memory page program with erase command code.*/
#define AT45_BUF2_MEM_ERASE 0x86
/** Buffer 1 to main memory page program without erase command code.*/
#define AT45_BUF1_MEM_NOERASE 0x88
/** Buffer 2 to main memory page program without erase command code.*/
#define AT45_BUF2_MEM_NOERASE 0x89
/** Page erase command code.*/
#define AT45_PAGE_ERASE 0x81
/** Block erase command code.*/
#define AT45_BLOCK_ERASE 0x50
/** Sector erase command code.*/
#define AT45_SECTOR_ERASE 0x7C
/** Chip erase command code.*/
#define AT45_CHIP_ERASE 0xC7, 0x94, 0x80, 0x9A
/** Main memory page program through buffer 1 command code.*/
#define AT45_PAGE_WRITE_BUF1 0x82
/** Main memory page program through buffer 2 command code.*/
#define AT45_PAGE_WRITE_BUF2 0x85
/** Main memory page to buffer 1 transfer command code.*/
#define AT45_PAGE_BUF1_TX 0x53
/** Main memory page to buffer 2 transfer command code.*/
#define AT45_PAGE_BUF2_TX 0x55
/** Main memory page to buffer 1 compare command code.*/
#define AT45_PAGE_BUF1_CMP 0x60
/** Main memory page to buffer 2 compare command code.*/
#define AT45_PAGE_BUF2_CMP 0x61
/** Auto page rewrite through buffer 1 command code.*/
#define AT45_AUTO_REWRITE_BUF1 0x58
/** Auto page rewrite through buffer 2 command code.*/
#define AT45_AUTO_REWRITE_BUF2 0x59
/** Deep power-down command code.*/
#define AT45_DEEP_PDOWN 0xB9
/** Resume from deep power-down command code.*/
#define AT45_RES_DEEP_PDOWN 0xAB
/** Status register read command code.*/
#define AT45_STATUS_READ 0xD7
/** Manufacturer and device ID read command code.*/
#define AT45_ID_READ 0x9F
/** Power-of-2 binary page size configuration command code.*/
#define AT45_BINARY_PAGE_FIRST_OPCODE 0x3D
#define AT45_BINARY_PAGE 0x2A, 0x80, 0xA6
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** Dataflash description. A constant array of DataflashDesc instance is defined
in at45.c. The DF_Scan() function returns the corresponding descriptor according
to the dataflash ID detected. This description (page_size, page_offset) is used
to compute the internal dataflash address by the DF_Command() function. */
typedef struct {
/** dataflash page number. */
uint32_t pageNumber;
// indicate if power-of-2 binary page supported.*/
uint32_t hasBinaryPage;
/** dataflash page size.*/
uint32_t pageSize;
/** page offset in command.*/
uint32_t pageOffset;
/** Dataflash ID.*/
uint8_t id;
/** Identifier.*/
const char *name;
} At45Desc;
/** Dataflash driver structure. It holds the current command being processed.
This structure is initialized by the DF_Init() command.
pDfDesc field can be initialized by the DF_Scan() function.
cmdBuffer is a private driver area used to compute the dataflash address to
be sent to the dataflash. Beware the PDC master must have access to this area.*/
typedef struct _Dataflash {
/** Pointer to Spi Structure (SPI low level driver).*/
Spid *pSpid;
/** Current SPI command sent to the SPI low level driver.*/
SpidCmd command;
/** Pointer to the dataflash description.*/
const At45Desc *pDesc;
/** Buffer to store the current command (opcode + dataflash address.*/
uint8_t pCmdBuffer[8];
} At45;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern uint8_t AT45_Configure(At45 *pAt45, Spid *pSpid, uint8_t spiCs);
extern uint8_t AT45_IsBusy(At45 *pAt45);
extern uint8_t AT45_SendCommand(
At45 *pAt45,
uint8_t cmd,
uint8_t cmdSize,
uint8_t *pData,
uint32_t dataSize,
uint32_t address,
SpidCallback callback,
void *pArgument);
extern const At45Desc * AT45_FindDevice(At45 *pAt45, uint8_t status);
extern uint32_t AT45_PageSize(At45 *pAt45);
#endif // #ifndef SPI_AT45_H
@@ -0,0 +1,275 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup spi_pdc_module SPI PDC driver
* The Spi driver is a low level spi driver which performs SPI device Initializes,
* spi transfer and receive. It can be used by upper SPI driver such as AT45
* driver and AT26 driver.
*
* \usage
* <ul>
* <li> Initializes a SPI instance and the corresponding SPI hardware,
* Configure SPI in Master Mode using SPID_Configure().</li>
* <li> Configures the SPI characteristics (such as Clock Polarity, Phase,
* transfers delay and Baud Rate) for the device corresponding to the
* chip select using SPID_ConfigureCS().</li>
* <li> Starts a SPI master transfer using SPID_SendCommand().
* The transfer is performed using the PDC channels. </li>
* <li> It enable the SPI clock.</li>
* <li> Set the corresponding peripheral chip select.</li>
* <li> Initialize the two SPI PDC buffers.</li>
* <li> Initialize SPI_TPR and SPI_TCR with SPI command data and size
* to send command data first.</li>
* <li> Initialize SPI_RPR and SPI_RCR with SPI command data and size
* as dummy value.</li>
* <li> Initialize SPI_TNPR and SPI_TNCR with rest of the data to be
* transfered.(if the data specified in cmd structure)</li>
* <li> Initialize SPI_RNPR and SPI_RNCR with rest of the data to be
* received.(if the data specified in cmd structure)</li>
* <li> Initialize the callback function if specified.</li>
* <li> Enable transmitter and receiver.</li>
* <li> Example for sending a command to the dataflash through the SPI.</li>
* \code
* /// Build command to be sent.
* ...
* // Send Command and data through the SPI
* if (SPID_SendCommand(pAt45->pSpid, pCommand)) {
* return AT45_ERROR_SPI;
* }
* \endcode
* <li> The SPI_Handler() must be called by the SPI Interrupt Service Routine
* with the corresponding Spi instance. It is invokes to check for pending
* interrupts. </li>
* <li> Example for initializing SPI interrupt handler in upper application.</li>
* \code
* AIC_ConfigureIT(AT91C_ID_SPI, 0, SPI_Handler);
* \endcode
* </ul>
* Related files :\n
* \ref spi_pdc.c\n
* \ref spi_pdc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of SPI PDC driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "spi_pdc.h"
#include <board.h>
/*----------------------------------------------------------------------------
* Macros
*----------------------------------------------------------------------------*/
/** Write PMC register*/
#define WRITE_PMC(pPmc, regName, value) pPmc->regName = (value)
/** Write SPI register*/
#define WRITE_SPI(pSpi, regName, value) pSpi->regName = (value)
/** Read SPI registers */
#define READ_SPI(pSpi, regName) (pSpi->regName)
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Initializes the Spid structure and the corresponding SPI hardware.
*
* \param pSpid Pointer to a Spid instance.
* \param pSpiHw Associated SPI peripheral.
* \param spiId SPI peripheral identifier.
* \return 0.
*/
uint8_t SPID_Configure(Spid *pSpid, Spi *pSpiHw, uint8_t spiId)
{
/* Initialize the SPI structure*/
pSpid->pSpiHw = pSpiHw;
pSpid->spiId = spiId;
pSpid->semaphore = 1;
pSpid->pCurrentCommand = 0;
/* Enable the SPI clock*/
WRITE_PMC(PMC, PMC_PCER0, (1 << pSpid->spiId));
/* Execute a software reset of the SPI twice */
WRITE_SPI(pSpiHw, SPI_CR, SPI_CR_SWRST);
WRITE_SPI(pSpiHw, SPI_CR, SPI_CR_SWRST);
/* Configure SPI in Master Mode with No CS selected !!! */
WRITE_SPI(pSpiHw, SPI_MR, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCS);
/* Enable the SPI*/
WRITE_SPI(pSpiHw, SPI_CR, SPI_CR_SPIEN);
/* Enable the SPI clock*/
WRITE_PMC(PMC, PMC_PCDR0, (1 << pSpid->spiId));
return 0;
}
/**
* \brief Configures the parameters for the device corresponding to the cs.
*
* \param pSpid Pointer to a Spid instance.
* \param cs number corresponding to the SPI chip select.
* \param csr SPI_CSR value to setup.
*/
void SPID_ConfigureCS(Spid *pSpid, uint8_t cs, uint32_t csr)
{
Spi *pSpiHw = pSpid->pSpiHw;
WRITE_SPI(pSpiHw, SPI_CSR[cs], csr);
}
/**
* \brief Starts a SPI master transfer. This is a non blocking function. It will
* return as soon as the transfer is started.
*
* \param pSpid Pointer to a Spid instance.
* \param pCommand Pointer to the SPI command to execute.
* \return 0 if the transfer has been started successfully; otherwise returns
* SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not
* valid.
*/
uint8_t SPID_SendCommand(Spid *pSpid, SpidCmd *pCommand)
{
Spi *pSpiHw = pSpid->pSpiHw;
uint32_t spiMr;
/* Try to get the dataflash semaphore */
if (pSpid->semaphore == 0) {
return SPID_ERROR_LOCK;
}
pSpid->semaphore--;
/* Enable the SPI clock */
WRITE_PMC(PMC, PMC_PCER0, (1 << pSpid->spiId));
/* Disable transmitter and receiver*/
WRITE_SPI(pSpiHw, SPI_PTCR, SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS);
/* Write to the MR register*/
spiMr = READ_SPI(pSpiHw, SPI_MR);
spiMr |= SPI_MR_PCS;
spiMr &= ~((1 << pCommand->spiCs) << 16);
WRITE_SPI(pSpiHw, SPI_MR, spiMr);
/* Initialize the two SPI PDC buffer*/
WRITE_SPI(pSpiHw, SPI_RPR, (int) pCommand->pCmd);
WRITE_SPI(pSpiHw, SPI_RCR, pCommand->cmdSize);
WRITE_SPI(pSpiHw, SPI_TPR, (int) pCommand->pCmd);
WRITE_SPI(pSpiHw, SPI_TCR, pCommand->cmdSize);
WRITE_SPI(pSpiHw, SPI_RNPR, (int) pCommand->pData);
WRITE_SPI(pSpiHw, SPI_RNCR, pCommand->dataSize);
WRITE_SPI(pSpiHw, SPI_TNPR, (int) pCommand->pData);
WRITE_SPI(pSpiHw, SPI_TNCR, pCommand->dataSize);
/* Initialize the callback*/
pSpid->pCurrentCommand = pCommand;
/* Enable transmitter and receiver*/
WRITE_SPI(pSpiHw, SPI_PTCR, SPI_PTCR_RXTEN | SPI_PTCR_TXTEN);
/* Enable buffer complete interrupt*/
WRITE_SPI(pSpiHw, SPI_IER, SPI_IER_RXBUFF);
return 0;
}
/**
* \brief The SPI_Handler must be called by the SPI Interrupt Service Routine with the
* corresponding Spi instance.
*
* \note The SPI_Handler will unlock the Spi semaphore and invoke the upper application
* callback.
* \param pSpid Pointer to a Spid instance.
*/
void SPID_Handler(Spid *pSpid)
{
SpidCmd *pSpidCmd = pSpid->pCurrentCommand;
Spi *pSpiHw = pSpid->pSpiHw;
volatile uint32_t spiSr;
/* Read the status register*/
spiSr = READ_SPI(pSpiHw, SPI_SR);
if (spiSr & SPI_SR_RXBUFF) {
/* Disable transmitter and receiver */
WRITE_SPI(pSpiHw, SPI_PTCR, SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS);
/* Disable the SPI clock*/
WRITE_PMC(PMC, PMC_PCDR0, (1 << pSpid->spiId));
/* Disable buffer complete interrupt */
WRITE_SPI(pSpiHw, SPI_IDR, SPI_IDR_RXBUFF);
/* Release the dataflash semaphore*/
pSpid->semaphore++;
/* Invoke the callback associated with the current command*/
if (pSpidCmd && pSpidCmd->callback) {
pSpidCmd->callback(0, pSpidCmd->pArgument);
}
/* Nothing must be done after. A new DF operation may have been started
in the callback function.*/
}
}
/**
* \brief Returns 1 if the SPI driver is currently busy executing a command; otherwise
* returns 0.
* \param pSpid Pointer to a Spid instance.
*/
uint8_t SPID_IsBusy(const Spid *pSpid)
{
if (pSpid->semaphore == 0) {
return 1;
}
else {
return 0;
}
}
@@ -0,0 +1,133 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of SPI PDC driver.
*
*/
#ifndef SPI_PDC_H
#define SPI_PDC_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** An unspecified error has occured.*/
#define SPID_ERROR 1
/** SPI driver is currently in use.*/
#define SPID_ERROR_LOCK 2
/*----------------------------------------------------------------------------
* Macros
*----------------------------------------------------------------------------*/
/** Calculates the value of the SCBR field of the Chip Select Register given MCK and SPCK.*/
#define SPID_CSR_SCBR(mck, spck) ((((mck) / (spck)) << 8) & SPI_CSR_SCBR)
/** Calculates the value of the DLYBS field of the Chip Select Register given delay in ns and MCK.*/
#define SPID_CSR_DLYBS(mck, delay) ((((((delay) * ((mck) / 1000000)) / 1000) + 1) << 16) & SPI_CSR_DLYBS)
/** Calculates the value of the DLYBCT field of the Chip Select Register given delay in ns and MCK.*/
#define SPID_CSR_DLYBCT(mck, delay) ((((((delay) / 32 * ((mck) / 1000000)) / 1000) + 1) << 24) & SPI_CSR_DLYBCT)
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** SPI transfer complete callback.*/
typedef void (*SpidCallback )(uint8_t, void *);
/** Spi Transfer Request prepared by the application upper layer. This structure
is sent to the SPI_SendCommand function to start the transfer. At the end of
the transfer, the callback is invoked by the interrupt handler.*/
typedef struct _SpidCmd {
/** Pointer to the command data.*/
uint8_t *pCmd;
/** Command size in bytes.*/
uint8_t cmdSize;
/** Pointer to the data to be sent.*/
uint8_t *pData;
/** Data size in bytes.*/
unsigned short dataSize;
/** SPI chip select.*/
uint8_t spiCs;
/** Callback function invoked at the end of transfer.*/
SpidCallback callback;
/** Callback arguments.*/
void *pArgument;
} SpidCmd;
/** Constant structure associated with SPI port. This structure prevents
client applications to have access in the same time.*/
typedef struct {
/** Pointer to SPI Hardware registers*/
Spi *pSpiHw;
/** SPI Id as defined in the product datasheet*/
char spiId;
/** Current SpiCommand being processed*/
SpidCmd *pCurrentCommand;
/** Mutual exclusion semaphore.*/
volatile char semaphore;
} Spid;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern uint8_t SPID_Configure(
Spid *pSpid,
Spi *pSpiHw,
uint8_t spiId);
extern void SPID_ConfigureCS(Spid *pSpid, uint8_t cs, uint32_t csr);
extern uint8_t SPID_SendCommand(
Spid *pSpid,
SpidCmd *pCommand);
extern void SPID_Handler(Spid *pSpid);
extern uint8_t SPID_IsBusy(const Spid *pSpid);
#endif // #ifndef SPI_PDC_H
+241
View File
@@ -0,0 +1,241 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup spi_module Working with SPI
* The SPI driver provides the interface to configure and use the SPI
* peripheral.
*
* The Serial Peripheral Interface (SPI) circuit is a synchronous serial
* data link that provides communication with external devices in Master
* or Slave Mode.
*
* To use the SPI, the user has to follow these few steps:
* -# Enable the SPI pins required by the application (see pio.h).
* -# Configure the SPI using the \ref SPI_Configure(). This enables the
* peripheral clock. The mode register is loaded with the given value.
* -# Configure all the necessary chip selects with \ref SPI_ConfigureNPCS().
* -# Enable the SPI by calling \ref SPI_Enable().
* -# Send/receive data using \ref SPI_Write() and \ref SPI_Read(). Note that \ref SPI_Read()
* must be called after \ref SPI_Write() to retrieve the last value read.
* -# Send/receive data using the PDC with the \ref SPI_WriteBuffer() and
* \ref SPI_ReadBuffer() functions.
* -# Disable the SPI by calling \ref SPI_Disable().
*
* For more accurate information, please look at the SPI section of the
* Datasheet.
*
* Related files :\n
* \ref spi.c\n
* \ref spi.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Serial Peripheral Interface (SPI) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include "spi.h"
#include "pmc/pmc.h"
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Enables a SPI peripheral.
*
* \param spi Pointer to an Spi instance.
*/
void SPI_Enable(Spi *spi)
{
spi->SPI_CR = SPI_CR_SPIEN;
}
/**
* \brief Disables a SPI peripheral.
*
* \param spi Pointer to an Spi instance.
*/
void SPI_Disable(Spi *spi)
{
spi->SPI_CR = SPI_CR_SPIDIS;
}
/**
* \brief Configures a SPI peripheral as specified. The configuration can be computed
* using several macros (see \ref spi_configuration_macros).
*
* \param spi Pointer to an Spi instance.
* \param id Peripheral ID of the SPI.
* \param configuration Value of the SPI configuration register.
*/
void SPI_Configure(Spi *spi,
uint32_t id,
uint32_t configuration)
{
PMC_EnablePeripheral(ID_SPI);
spi->SPI_CR = SPI_CR_SPIDIS;
/* Execute a software reset of the SPI twice */
spi->SPI_CR = SPI_CR_SWRST;
spi->SPI_CR = SPI_CR_SWRST;
spi->SPI_MR = configuration;
}
/**
* \brief Configures a chip select of a SPI peripheral. The chip select configuration
* is computed using several macros (see \ref spi_configuration_macros).
*
* \param spi Pointer to an Spi instance.
* \param npcs Chip select to configure (0, 1, 2 or 3).
* \param configuration Desired chip select configuration.
*/
void SPI_ConfigureNPCS(Spi *spi,
uint32_t npcs,
uint32_t configuration)
{
spi->SPI_CSR[npcs] = configuration;
}
/**
* \brief Sends data through a SPI peripheral. If the SPI is configured to use a fixed
* peripheral select, the npcs value is meaningless. Otherwise, it identifies
* the component which shall be addressed.
*
* \param spi Pointer to an Spi instance.
* \param npcs Chip select of the component to address (0, 1, 2 or 3).
* \param data Word of data to send.
*/
void SPI_Write(Spi *spi, uint32_t npcs, uint16_t data)
{
/* Send data */
while ((spi->SPI_SR & SPI_SR_TXEMPTY) == 0);
spi->SPI_TDR = data | SPI_PCS(npcs);
while ((spi->SPI_SR & SPI_SR_TDRE) == 0);
}
/**
* \brief Sends the contents of buffer through a SPI peripheral, using the PDC to
* take care of the transfer.
*
* \param spi Pointer to an Spi instance.
* \param buffer Data buffer to send.
* \param length Length of the data buffer.
*/
uint8_t SPI_WriteBuffer(Spi *spi,
void *buffer,
uint32_t length)
{
/* Check if first bank is free */
if (spi->SPI_TCR == 0) {
spi->SPI_TPR = (uint32_t) buffer;
spi->SPI_TCR = length;
spi->SPI_PTCR = PERIPH_PTCR_TXTEN;
return 1;
}
/* Check if second bank is free */
else if (spi->SPI_TNCR == 0) {
spi->SPI_TNPR = (uint32_t) buffer;
spi->SPI_TNCR = length;
return 1;
}
/* No free banks */
return 0;
}
/**
* \brief Check if SPI transfer finish.
*
* \param spi Pointer to an Spi instance.
*
* \return Returns 1 if there is no pending write operation on the SPI; otherwise
* returns 0.
*/
uint8_t SPI_IsFinished(Spi *spi)
{
return ((spi->SPI_SR & SPI_SR_TXEMPTY) != 0);
}
/**
* \brief Reads and returns the last word of data received by a SPI peripheral. This
* method must be called after a successful SPI_Write call.
*
* \param spi Pointer to an Spi instance.
*
* \return readed data.
*/
uint16_t SPI_Read(Spi *spi)
{
while ((spi->SPI_SR & SPI_SR_RDRF) == 0);
return spi->SPI_RDR & 0xFFFF;
}
/**
* \brief Reads data from a SPI peripheral until the provided buffer is filled. This
* method does NOT need to be called after SPI_Write or SPI_WriteBuffer.
*
* \param spi Pointer to an Spi instance.
* \param buffer Data buffer to store incoming bytes.
* \param length Length in bytes of the data buffer.
*/
uint8_t SPI_ReadBuffer(Spi *spi,
void *buffer,
uint32_t length)
{
/* Check if the first bank is free */
if (spi->SPI_RCR == 0) {
spi->SPI_RPR = (uint32_t) buffer;
spi->SPI_RCR = length;
spi->SPI_PTCR = PERIPH_PTCR_RXTEN;
return 1;
}
/* Check if second bank is free */
else if (spi->SPI_RNCR == 0) {
spi->SPI_RNPR = (uint32_t) buffer;
spi->SPI_RNCR = length;
return 1;
}
/* No free bank */
return 0;
}
+104
View File
@@ -0,0 +1,104 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for Serial Peripheral Interface (SPI) controller.
*
*/
#ifndef SPI_H
#define SPI_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
/*----------------------------------------------------------------------------
* Macros
*----------------------------------------------------------------------------*/
/**
* \page spi_configuration_macros SPI configuration macros
*
* This page lists several macros which should be used when configuring a SPI
* peripheral.
*
* \par Macros:
* - \ref SPI_PCS
* - \ref SPI_SCBR
* - \ref SPI_DLYBS
* - \ref SPI_DLYBCT
*/
/** Calculate the PCS field value given the chip select NPCS value */
#define SPI_PCS(npcs) ((~(1 << npcs) & 0xF) << 16)
/** Calculates the value of the CSR SCBR field given the baudrate and MCK. */
#define SPI_SCBR(baudrate, masterClock) \
((uint32_t) (masterClock / baudrate) << 8)
/** Calculates the value of the CSR DLYBS field given the desired delay (in ns) */
#define SPI_DLYBS(delay, masterClock) \
((uint32_t) (((masterClock / 1000000) * delay) / 1000) << 16)
/** Calculates the value of the CSR DLYBCT field given the desired delay (in ns) */
#define SPI_DLYBCT(delay, masterClock) \
((uint32_t) (((masterClock / 1000000) * delay) / 32000) << 24)
/*------------------------------------------------------------------------------ */
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void SPI_Enable(Spi *spi);
extern void SPI_Disable(Spi *spi);
extern void SPI_Configure(Spi *spi,
uint32_t id,
uint32_t configuration);
extern void SPI_ConfigureNPCS(Spi *spi,
uint32_t npcs,
uint32_t configuration);
extern void SPI_Write(Spi *spi, uint32_t npcs, uint16_t data);
extern uint8_t SPI_WriteBuffer(Spi *spi,
void *buffer,
uint32_t length);
extern uint8_t SPI_IsFinished(Spi *pSpi);
extern uint16_t SPI_Read(Spi *spi);
extern uint8_t SPI_ReadBuffer(Spi *spi,
void *buffer,
uint32_t length);
#endif /* #ifndef SPI_H */
+248
View File
@@ -0,0 +1,248 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup ssc module Working with SSC
* The SSC driver provides the interface to configure and use the SSC
* peripheral.
*
* !Usage
*
* -# Enable the SSC interface pins.
* -# Configure the SSC to operate at a specific frequency by calling
* SSC_Configure(). This function enables the peripheral clock of the SSC,
* but not its PIOs.
* -# Configure the transmitter and/or the receiver using the
* SSC_ConfigureTransmitter() and SSC_ConfigureEmitter() functions.
* -# Enable the PIOs or the transmitter and/or the received.
* -# Enable the transmitter and/or the receiver using SSC_EnableTransmitter()
* and SSC_EnableReceiver()
* -# Send data through the transmitter using SSC_Write() and SSC_WriteBuffer()
* -# Receive data from the receiver using SSC_Read() and SSC_ReadBuffer()
* -# Disable the transmitter and/or the receiver using SSC_DisableTransmitter()
* and SSC_DisableReceiver()
*
* For more accurate information, please look at the RTC section of the
* Datasheet.
*
* Related files :\n
* \ref ssc.c\n
* \ref ssc.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Synchronous Serial (SSC) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include "ssc.h"
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Configures a SSC peripheral.If the divided clock is not used, the master
* clock frequency can be set to 0.
* \note The emitter and transmitter are disabled by this function.
* \param bitRate bit rate.
* \param masterClock master clock.
*/
void SSC_Configure(uint32_t bitRate, uint32_t masterClock)
{
/* Enable SSC peripheral clock */
PMC->PMC_PCER0 = 1 << ID_SSC;
/* Reset, disable receiver & transmitter */
SSC->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST;
SSC->SSC_PTCR = SSC_PTCR_RXTDIS | SSC_PTCR_TXTDIS;
/* Configure clock frequency */
if (bitRate != 0) {
SSC->SSC_CMR = masterClock / (2 * bitRate);
}
else {
SSC->SSC_CMR = 0;
}
}
/**
* \brief Configures the transmitter of a SSC peripheral.
* \param tcmr Transmit Clock Mode Register value.
* \param tfmr Transmit Frame Mode Register value.
*/
void SSC_ConfigureTransmitter(uint32_t tcmr, uint32_t tfmr)
{
SSC->SSC_TCMR = tcmr;
SSC->SSC_TFMR = tfmr;
}
/**
* \brief Configures the receiver of a SSC peripheral.
* \param rcmr Receive Clock Mode Register value.
* \param rfmr Receive Frame Mode Register value.
*/
void SSC_ConfigureReceiver(uint32_t rcmr, uint32_t rfmr)
{
SSC->SSC_RCMR = rcmr;
SSC->SSC_RFMR = rfmr;
}
/**
* \brief Enables the transmitter of a SSC peripheral.
*/
void SSC_EnableTransmitter(void)
{
SSC->SSC_CR = SSC_CR_TXEN;
}
/**
* \brief Disables the transmitter of a SSC peripheral.
*/
void SSC_DisableTransmitter(void)
{
SSC->SSC_CR = SSC_CR_TXDIS;
}
/**
* \brief Enables the receiver of a SSC peripheral.
*/
void SSC_EnableReceiver(void)
{
SSC->SSC_CR = SSC_CR_RXEN;
}
/**
* \brief Disables the receiver of a SSC peripheral.
*/
void SSC_DisableReceiver(void)
{
SSC->SSC_CR = SSC_CR_RXDIS;
}
/**
* \brief Enables one or more interrupt sources of a SSC peripheral.
* \param Bitwise OR of selected interrupt sources.
*/
void SSC_EnableInterrupts(uint32_t sources)
{
SSC->SSC_IER = sources;
}
/**
* \brief Disables one or more interrupt sources of a SSC peripheral.
* \param Bitwise OR of selected interrupt sources.
*/
void SSC_DisableInterrupts(uint32_t sources)
{
SSC->SSC_IDR = sources;
}
/**
* \brief Sends one data frame through a SSC peripheral. If another frame is currently
* being sent, this function waits for the previous transfer to complete.
* \param frame Data frame to send.
*/
void SSC_Write(uint32_t frame)
{
while ((SSC->SSC_SR & SSC_SR_TXRDY) == 0);
SSC->SSC_THR = frame;
}
/**
* \brief Waits until one frame is received on a SSC peripheral, and returns it.
*/
uint32_t SSC_Read(void)
{
while ((SSC->SSC_SR & SSC_SR_RXRDY) == 0);
return SSC->SSC_RHR;
}
/**
* \brief Sends the contents of a data buffer a SSC peripheral, using the PDC.
* \param buffer Data buffer to send.
* \param length Size of the data buffer.
* \return 1 if the buffer has been queued for transmission; otherwise returns 0.
*/
uint8_t SSC_WriteBuffer(void *buffer, uint32_t length)
{
/* Check if first bank is free*/
if (SSC->SSC_TCR == 0) {
SSC->SSC_TPR = (uint32_t) buffer;
SSC->SSC_TCR = length;
SSC->SSC_PTCR = SSC_PTCR_TXTEN;
return 1;
}
/* Check if second bank is free*/
else if (SSC->SSC_TNCR == 0) {
SSC->SSC_TNPR = (uint32_t) buffer;
SSC->SSC_TNCR = length;
return 1;
}
return 0;
}
/**
* \brief Reads data coming from a SSC peripheral receiver and stores it into the
* giving buffer with PDC.
* \param buffer ata buffer used for reception.
* \param length Size of the data buffer.
* \return 1 if the buffer has been queued for reception; otherwise returns 0.
*/
uint8_t SSC_ReadBuffer(void *buffer, uint32_t length)
{
/* Check if the first bank is free*/
if (SSC->SSC_RCR == 0) {
SSC->SSC_RPR = (uint32_t) buffer;
SSC->SSC_RCR = length;
SSC->SSC_PTCR = SSC_PTCR_RXTEN;
return 1;
}
/* Check if second bank is free*/
else if (SSC->SSC_RNCR == 0) {
SSC->SSC_RNPR = (uint32_t) buffer;
SSC->SSC_RNCR = length;
return 1;
}
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for Synchronous Serial (SSC) controller.
*
*/
#ifndef SSC_H
#define SSC_H
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void SSC_Configure(uint32_t bitRate, uint32_t masterClock);
extern void SSC_ConfigureTransmitter(uint32_t tcmr, uint32_t tfmr);
extern void SSC_ConfigureReceiver(uint32_t rcmr, uint32_t rfmr);
extern void SSC_EnableTransmitter(void);
extern void SSC_DisableTransmitter(void);
extern void SSC_EnableReceiver(void);
extern void SSC_DisableReceiver(void);
extern void SSC_EnableInterrupts(uint32_t sources);
extern void SSC_DisableInterrupts(uint32_t sources);
extern void SSC_Write(uint32_t frame);
extern uint32_t SSC_Read(void);
extern uint8_t SSC_WriteBuffer(void *buffer, uint32_t length);
extern uint8_t SSC_ReadBuffer(void *buffer, uint32_t length);
#endif //#ifndef SSC_H
+148
View File
@@ -0,0 +1,148 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include "tc.h"
/*------------------------------------------------------------------------------
* Global functions
*------------------------------------------------------------------------------*/
/**------------------------------------------------------------------------------
* \brief Configures a Timer Counter Channel
* Configures a Timer Counter to operate in the given mode. Timer is stopped
* after configuration and must be restarted with TC_Start(). All the
* interrupts of the timer are also disabled.
* \param pTc Pointer to an AT91S_TC instance.
* \param channel Channel number.
* \param mode Operating mode (TC_CMR value).
*------------------------------------------------------------------------------*/
void TC_Configure(Tc *pTc, unsigned char channel, unsigned int mode)
{
TcChannel *pTcCh = &pTc->TC_CHANNEL[channel];
/* Disable TC clock */
pTcCh->TC_CCR = TC_CCR0_CLKDIS;
/* Disable interrupts */
pTcCh->TC_IDR = 0xFFFFFFFF;
/* Clear status register */
pTcCh->TC_SR;
/* Set mode */
pTcCh->TC_CMR = mode;
}
/**------------------------------------------------------------------------------
* \brief Reset and Start the TC Channel
* Enables the timer clock and performs a software reset to start the counting.
* \param pTc Pointer to an AT91S_TC instance.
* \param channel Channel number.
*------------------------------------------------------------------------------*/
void TC_Start(Tc *pTc, unsigned char channel)
{
TcChannel *pTcCh = &pTc->TC_CHANNEL[channel];
pTcCh->TC_CCR = TC_CCR0_CLKEN | TC_CCR0_SWTRG;
}
/**------------------------------------------------------------------------------
* \brief Stop TC Channel
* Disables the timer clock, stopping the counting.
* \param pTc Pointer to an AT91S_TC instance.
* \param channel Channel number.
*------------------------------------------------------------------------------*/
void TC_Stop(Tc *pTc, unsigned char channel)
{
TcChannel *pTcCh = &pTc->TC_CHANNEL[channel];
pTcCh->TC_CCR = TC_CCR0_CLKDIS;
}
/**------------------------------------------------------------------------------
* \brief Find best MCK divisor
* Finds the best MCK divisor given the timer frequency and MCK. The result
* is guaranteed to satisfy the following equation:
* \pre
* (MCK / (DIV * 65536)) <= freq <= (MCK / DIV)
* \endpre
* with DIV being the highest possible value.
* \param freq Desired timer frequency.
* \param mck Master clock frequency.
* \param div Divisor value.
* \param tcclks TCCLKS field value for divisor.
* \return 1 if a proper divisor has been found; otherwise 0.
*------------------------------------------------------------------------------*/
unsigned char TC_FindMckDivisor(
unsigned int freq,
unsigned int mck,
unsigned int *div,
unsigned int *tcclks)
{
const unsigned int divisors[5] = {2, 8, 32, 128,BOARD_MCK / 32768};
unsigned int index = 0;
/* Satisfy lower bound */
while (freq < ((mck / divisors[index]) / 65536)) {
index++;
/* If no divisor can be found, return 0 */
if (index == 5) {
return 0;
}
}
/* Try to maximize DIV while satisfying upper bound */
while (index < 4) {
if (freq > (mck / divisors[index + 1])) {
break;
}
index++;
}
/* Store results */
if (div) {
*div = divisors[index];
}
if (tcclks) {
*tcclks = index;
}
return 1;
}
+70
View File
@@ -0,0 +1,70 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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
*
* API for configuring and using Timer Counter (TC) peripherals.
*
* Usage
* -# Optionally, use TC_FindMckDivisor() to let the program find the best
* TCCLKS field value automatically.
* -# Configure a Timer Counter in the desired mode using TC_Configure().
* -# Start or stop the timer clock using TC_Start() and TC_Stop().
*------------------------------------------------------------------------------*/
#ifndef TC_H
#define TC_H
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include <board.h>
/*------------------------------------------------------------------------------
* Global functions
*------------------------------------------------------------------------------*/
extern void TC_Configure(Tc *pTc, unsigned char ch, unsigned int mode);
extern void TC_Start(Tc *pTc, unsigned char ch);
extern void TC_Stop(Tc *pTc, unsigned char ch);
extern unsigned char TC_FindMckDivisor(
unsigned int freq,
unsigned int mck,
unsigned int *div,
unsigned int *tcclks);
#endif /* #ifndef TC_H */
+69
View File
@@ -0,0 +1,69 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for touchscreen driver which includes touchscreen calibration,
* retrieving measurements etc.
*
* \par Usage
*
* -# Call TSD_Initialize() whenever the touchscreen should start the
* calibration process (as it is done in the function).
* -# Declare a global TSD_PenPressed function anywhere in your code. This
* function will get called every time the pen is pressed on the screen.
* -# Declare a global TSD_PenMoved function, which will get called whenever
* the pen stays in contact with the screen but changes position.
* -# Declare a global TSD_PenReleased function, which will be invoked as the
* pen is lifted from the screen.
*/
#ifndef TSD_H
#define TSD_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "tsd_com.h"
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void TSD_Initialize(int8_t calEn);
extern uint8_t TSD_Calibrate(void);
extern void TSD_Reset(void);
extern void TSD_TimerHandler(void);
#endif /* #ifndef TSD_H */
@@ -0,0 +1,302 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of ADS7843 driver.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <board.h>
#include <string.h>
#ifdef BOARD_TSC_ADS7843
#include "tsd.h"
#include "tsd_com.h"
#include <pio/pio.h>
#include <pio/pio_it.h>
#include <ads7843/ads7843.h>
#include <lcd/lcdd.h>
#include <lcd/draw.h>
#include <lcd/font.h>
#include "tsd/tsd_ads7843.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Delay for pushbutton debouncing (the time-base is 10 ms). */
#define DEBOUNCE_TIME 6 /* 10 * 6 = 60 ms */
/** Color of calibration points. */
#define POINTS_COLOR 0x0000FF
/** Size in pixels of calibration points. */
#define POINTS_SIZE 4
/** Maximum difference in pixels between the test point and the measured point. */
#define POINTS_MAX_ERROR 5
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** pen state */
typedef enum {
STATE_PEN_RELEASED = 0,
STATE_PEN_PRESSED = 1,
STATE_PEN_DEBOUNCE = 2
} e_pen_state;
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** Pins used by Interrupt Signal for Touch Screen Controller */
static const Pin pinPenIRQ = PIN_TCS_IRQ;
/** Global timestamp in milliseconds since start of application. */
static volatile uint32_t timestamp = 0;
/** last time when the pen is pressed on the touchscreen */
static volatile uint32_t timePress = 0;
/** last time when the pen is released */
static volatile uint32_t timeRelease = 0;
/** pen state */
static volatile e_pen_state penState = STATE_PEN_RELEASED;
/** Touch screen initiallized flag */
static uint32_t tsInitFlag = 0;
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Timer handler for touch screen. Increments the timestamp counter.
* Determine the state "Pen Pressed" or "Pen Released". To change state,
* the penIRQ has to keep the same value during DEBOUNCE_TIME.
*
* \note External timer interrupt should call it per 10ms.
*/
extern void TSD_TimerHandler( void )
{
uint32_t data[2];
static uint32_t point[2];
if (!tsInitFlag) return;
timestamp++;
/* Get the current position of the pen if penIRQ has low value (pen pressed) */
if (PIO_Get(&pinPenIRQ) == 0) {
/* Get the current position of the pressed pen */
if(TSDCom_IsCalibrationOk()) {
TSD_GetRawMeasurement(data);
TSDCom_InterpolateMeasurement(data, point);
}
/* call the callback function */
if(penState == STATE_PEN_PRESSED) {
if(TSDCom_IsCalibrationOk()) {
TSD_PenMoved(point[0], point[1]);
}
}
}
/* Determine the pen state */
if (PIO_Get(&pinPenIRQ) == 0) {
/* reinit the last time when release */
timeRelease = timestamp;
if(penState == STATE_PEN_DEBOUNCE) {
if( (timestamp - timePress) > DEBOUNCE_TIME) {
/* pen is pressed during an enough time : the state change */
penState = STATE_PEN_PRESSED;
/* call the callback function */
if(TSDCom_IsCalibrationOk()) {
TSD_PenPressed(point[0], point[1]);
}
}
}
}
else {
/* reinit the last time when release */
timePress = timestamp;
if(penState == STATE_PEN_DEBOUNCE) {
if( (timestamp - timeRelease) > DEBOUNCE_TIME) {
/* pen is released during an enough time : the state change */
penState = STATE_PEN_RELEASED;
/* call the callback function */
if(TSDCom_IsCalibrationOk()) {
TSD_PenReleased(point[0], point[1]);
}
}
}
}
}
/**
* \breif Interrupt handler for Touchscreen.
*/
static void ISR_PenIRQ(void)
{
/* Check if the pen has been pressed */
if (!PIO_Get(&pinPenIRQ)) {
if(penState == STATE_PEN_RELEASED) {
timePress = timestamp;
penState = STATE_PEN_DEBOUNCE;
}
}
else {
if(penState == STATE_PEN_PRESSED) {
timeRelease = timestamp;
penState = STATE_PEN_DEBOUNCE;
}
}
}
/**
* \brief Configure PENIRQ for interrupt.
*/
static void ConfigurePenIRQ(void)
{
/* Configure pios */
PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ));
/* Initialize interrupts */
PIO_InitializeInterrupts(0);
PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ);
/* Enable the interrupt */
PIO_EnableIt(&pinPenIRQ);
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Reads and store a touchscreen measurement in the provided array.
*
* \param pData Array where the measurements will be stored
*/
extern void TSD_GetRawMeasurement(uint32_t *pData)
{
/* Get the current position of the pressed pen */
PIO_DisableIt(&pinPenIRQ);
ADS7843_GetPosition(&pData[0], &pData[1]);
PIO_EnableIt(&pinPenIRQ);
}
/**
* \brief Wait pen pressed.
*/
extern void TSD_WaitPenPressed( void )
{
/* Wait for touch & end of conversion */
while (penState != STATE_PEN_RELEASED);
/*while (penState != STATE_PEN_PRESSED); */
while (penState != STATE_PEN_PRESSED) {
}
}
/**
* \brief Wait pen released.
*/
extern void TSD_WaitPenReleased( void )
{
/* Wait for contact loss */
while (penState != STATE_PEN_PRESSED);
while (penState != STATE_PEN_RELEASED);
}
/**
* \brief Do calibration.
*
* \return 1 if calibration is Ok, 0 else.
*/
uint8_t TSD_Calibrate(void)
{
uint8_t ret = 0;
/* Calibration is done only once */
if(TSDCom_IsCalibrationOk()) {
return 1;
}
/* Do calibration */
ret = TSDCom_Calibrate();
return ret;
}
/**
* \brief Initializes the touchscreen driver and starts the calibration process. When
* finished, the touchscreen is operational.
*
* \note Important: the LCD driver must have been initialized prior to calling this
* function.
*/
extern void TSD_Initialize( int8_t calEn )
{
ADS7843_Initialize();
ConfigurePenIRQ();
tsInitFlag = 1;
/* Calibration */
if(calEn) {
while (!TSD_Calibrate());
}
}
/**
* \brief Stop the Touchscreen, disable interrupt.
*/
void TSD_Reset(void)
{
/* Disable SPI 0 */
ADS7843_Reset();
/* Disable the interrupt */
PIO_DisableIt(&pinPenIRQ);
}
#endif /* #ifdef BOARD_TSC_ADS7843 */
@@ -0,0 +1,20 @@
#ifndef _TSD_ADS7843_
#define _TSD_ADS7843_
/*----------------------------------------------------------------------------
* External functions
*----------------------------------------------------------------------------*/
extern void TSD_PenPressed( uint32_t dwX, uint32_t dwY ) ;
extern void TSD_PenMoved( uint32_t dwX, uint32_t dwY ) ;
extern void TSD_PenReleased( uint32_t dwX, uint32_t dwY ) ;
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void TSD_WaitPenPressed( void ) ;
extern void TSD_WaitPenReleased( void ) ;
extern void TSD_GetRawMeasurement( uint32_t *pData ) ;
extern void TSD_Initialize( int8_t calEn ) ;
#endif // _TSD_ADS7843_
+380
View File
@@ -0,0 +1,380 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of touchscreen driver device irrelevance code.
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdint.h>
#include <string.h>
#include "tsd.h"
#include <board.h>
#include <pio/pio.h>
#include <lcd/lcdd.h>
#include <lcd/draw.h>
#include <lcd/font.h>
#include <lcd/color.h>
#include <utility/assert.h>
#include "tsd/tsd_ads7843.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Size in pixels of calibration points. */
#define POINTS_SIZE 4
/** Maximum difference in pixels between the test point and the measured point. */
#define POINTS_MAX_ERROR 8
/** Delay at the end of calibartion for result display */
#define DELAY_RESULT_DISPLAY 4000000
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** Point used during the touchscreen calibration process. */
typedef struct _CalibrationPoint {
/** Coordinate of point along the X-axis of the screen. */
uint32_t x;
/** Coordinate of point along the Y-axis of the screen. */
uint32_t y;
/** Calibration data of point. */
uint32_t data[2];
} CalibrationPoint;
/*----------------------------------------------------------------------------
* Variables
*----------------------------------------------------------------------------*/
/** indicates if the touch screen has been calibrated. */
/** If not, Callback functions are not called. */
static volatile uint8_t bCalibrationOk = 1 ; //0;
/** Slope for interpoling touchscreen measurements along the X-axis. */
static int32_t xSlope;
/** Slope for interpoling touchscreen measurements along the Y-axis. */
static int32_t ySlope;
/** Calibration points. */
static CalibrationPoint calibrationPoints[] = {
/* Top-left corner calibration point */
{
BOARD_LCD_WIDTH / 10,
BOARD_LCD_HEIGHT / 10,
{0, 0}
},
/* Top-right corner calibration point */
{
BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
BOARD_LCD_HEIGHT / 10,
{0, 0}
},
/* Bottom-right corner calibration point */
{
BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
{0, 0}
},
/* Bottom-left corner calibration point */
{
BOARD_LCD_WIDTH / 10,
BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
{0, 0}
}
};
/** Test point */
static const CalibrationPoint testPoint = {
BOARD_LCD_WIDTH / 2,
BOARD_LCD_HEIGHT / 2,
{0, 0}
};
/*----------------------------------------------------------------------------
* External functions
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/*
* \brief Display a calibration point on the given buffer.
*
* \param pPoint Calibration point to display.
*/
static void DrawCalibrationPoint(const CalibrationPoint *pPoint)
{
LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
pPoint->y - POINTS_SIZE / 2,
POINTS_SIZE,
POINTS_SIZE,
COLOR_RED);
}
/**
* \brief Clears a calibration point from the given buffer.
*
* \param pPoint Calibration point to clear.
*/
static void ClearCalibrationPoint(const CalibrationPoint *pPoint)
{
LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
pPoint->y - POINTS_SIZE / 2,
POINTS_SIZE,
POINTS_SIZE,
COLOR_WHITE);
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \breif Indicates if the calibration of the touch screen is Ok.
*
* \return 1 calibration Ok, 0 if not.
*/
uint8_t TSDCom_IsCalibrationOk(void)
{
if (bCalibrationOk == 1) {
return 1;
} else {
return 0;
}
}
/**
* \brief Interpolates the provided raw measurements using the previously calculated
* slope. The resulting x and y coordinates are stored in an array.
*
* \param pData Raw measurement data, as returned by TSD_GetRawMeasurement().
* \param pPoint Array in which x and y will be stored.
*/
void TSDCom_InterpolateMeasurement(const uint32_t *pData, uint32_t *pPoint)
{
pPoint[0] = calibrationPoints[0].x
- (((int32_t) calibrationPoints[0].data[0] - (int32_t) pData[0]) * 1024)
/ xSlope;
pPoint[1] = calibrationPoints[0].y
- (((int32_t) calibrationPoints[0].data[1] - (int32_t) pData[1]) * 1024)
/ ySlope;
if(pPoint[0] & 0x80000000) /* Is pPoint[0] negative ? */
{
pPoint[0] = 0;
}
if(pPoint[0] > BOARD_LCD_WIDTH) /* Is pPoint[0] bigger than the LCD width ? */
{
pPoint[0] = BOARD_LCD_WIDTH;
}
if(pPoint[1] & 0x80000000) /* Is pPoint[1] negative ? */
{
pPoint[1] = 0;
}
if(pPoint[1] > BOARD_LCD_HEIGHT) /* Is pPoint[1] bigger than the LCD width ? */
{
pPoint[1] = BOARD_LCD_HEIGHT;
}
}
/**
* \brief Performs the calibration process using the provided buffer to display
* information.
*
* \return True if calibration was successful; otherwise false.
*/
uint8_t TSDCom_Calibrate(void)
{
volatile uint32_t i; /* to keep the tempo with gcc code optimisation */
int32_t slope1, slope2;
CalibrationPoint measuredPoint;
uint8_t xOk, yOk;
int32_t xDiff, yDiff;
/* Calibration setup */
LCDD_Fill(COLOR_WHITE);
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
LCDD_DrawString(1, 140, (uint8_t *)"Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);
/* Calibration points */
for (i=0; i < 4; i++) {
DrawCalibrationPoint(&calibrationPoints[i]);
/* Wait for touch & end of conversion */
TSD_WaitPenPressed();
TSD_GetRawMeasurement(calibrationPoints[i].data);
ClearCalibrationPoint(&calibrationPoints[i]);
/* Wait for contact loss */
TSD_WaitPenReleased();
}
/**
* Calculate slopes using the calibration data
* Theory behind those calculations:
* - We suppose the touchscreen measurements are linear, so the following equations are true (simple
* linear regression) for any two 'a' and 'b' points of the screen:
* dx = (a.data[0] - b.data[0]) / (a.x - b.x)
* dy = (a.data[1] - b.data[1]) / (a.y - b.y)
*
* - We calculate dx and dy (called xslope and yslope here) using the calibration points.
*
* - We can then use dx and dy to infer the position of a point 'p' given the measurements performed
* by the touchscreen ('c' is any of the calibration points):
* dx = (p.data[0] - c.data[0]) / (p.x - c.x)
* dy = (p.data[1] - c.data[1]) / (p.y - c.y)
* Thus:
* p.x = c.x - (p.data[0] - c.data[0]) / dx
* p.y = c.y - (p.data[1] - c.data[1]) / dy
*
* - Since there are four calibration points, dx and dy can be calculated twice, so we average
* the two values.
*/
slope1 = ((int32_t) calibrationPoints[0].data[0]) - ((int32_t) calibrationPoints[1].data[0]);
slope1 *= 1024;
slope1 /= ((int32_t) calibrationPoints[0].x) - ((int32_t) calibrationPoints[1].x);
slope2 = ((int32_t) calibrationPoints[2].data[0]) - ((int32_t) calibrationPoints[3].data[0]);
slope2 *= 1024;
slope2 /= ((int32_t) calibrationPoints[2].x) - ((int32_t) calibrationPoints[3].x);
xSlope = (slope1 + slope2) / 2;
slope1 = ((int32_t) calibrationPoints[0].data[1]) - ((int32_t) calibrationPoints[2].data[1]);
slope1 *= 1024;
slope1 /= ((int32_t) calibrationPoints[0].y) - ((int32_t) calibrationPoints[2].y);
slope2 = ((int32_t) calibrationPoints[1].data[1]) - ((int32_t) calibrationPoints[3].data[1]);
slope2 *= 1024;
slope2 /= ((int32_t) calibrationPoints[1].y) - ((int32_t) calibrationPoints[3].y);
ySlope = (slope1 + slope2) / 2;
/* Test point */
LCDD_Fill(0xFFFFFF);
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
LCDD_DrawString(1, 100, (uint8_t *)" Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
DrawCalibrationPoint(&testPoint);
/* Wait for touch & end of conversion */
TSD_WaitPenPressed();
TSD_GetRawMeasurement(measuredPoint.data);
TSDCom_InterpolateMeasurement(measuredPoint.data, (uint32_t *) &measuredPoint);
DrawCalibrationPoint(&measuredPoint);
/* Check resulting x and y */
xDiff = (int32_t) measuredPoint.x - (int32_t) testPoint.x;
yDiff = (int32_t) measuredPoint.y - (int32_t) testPoint.y;
xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR);
yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR);
/* Wait for contact loss */
TSD_WaitPenReleased();
/* Check calibration result */
if (xOk && yOk) {
bCalibrationOk = 1;
LCDD_Fill(COLOR_WHITE);
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
LCDD_DrawString(80, 140, (uint8_t *)"Success !", COLOR_GREEN);
}
else {
bCalibrationOk = 0;
LCDD_Fill(COLOR_WHITE);
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
LCDD_DrawString(40, 140, (uint8_t *)"Error too big", COLOR_RED);
}
/* Slight delay */
for (i = 0; i < DELAY_RESULT_DISPLAY; i++);
return (xOk && yOk);
}
/**
* \brief Read calibrate data to buffer.
*
* \param pBuffer Data buffer.
* \param size Size of data buffer in bytes.
*/
void TSDCom_ReadCalibrateData(void *pBuffer, uint32_t size)
{
uint8_t *pDest = (uint8_t *)pBuffer;
SANITY_CHECK((sizeof(bCalibrationOk) + sizeof(xSlope) +
sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size);
memcpy(pDest, (void const *)&bCalibrationOk, sizeof(bCalibrationOk));
pDest += sizeof(bCalibrationOk);
memcpy(pDest, &xSlope, sizeof(xSlope));
pDest += sizeof(xSlope);
memcpy(pDest, &ySlope, sizeof(ySlope));
pDest += sizeof(ySlope);
memcpy(pDest, &calibrationPoints[0].data, sizeof(calibrationPoints[0].data));
pDest += sizeof(calibrationPoints[0].data);
}
/**
* \brief Restore calibrate data with buffer data.
*
* \param pBuffer Data buffer.
* \param size Size of data buffer in bytes.
*/
void TSDCom_RestoreCalibrateData(void *pBuffer, uint32_t size)
{
uint8_t *pSrc = (uint8_t *)pBuffer;
SANITY_CHECK((sizeof(bCalibrationOk) + sizeof(xSlope) +
sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size);
memcpy((void *)&bCalibrationOk, pSrc, sizeof(bCalibrationOk));
pSrc += sizeof(bCalibrationOk);
memcpy(&xSlope, pSrc, sizeof(xSlope));
pSrc += sizeof(xSlope);
memcpy(&ySlope, pSrc, sizeof(ySlope));
pSrc += sizeof(ySlope);
memcpy(&calibrationPoints[0].data, pSrc, sizeof(calibrationPoints[0].data));
pSrc += sizeof(calibrationPoints[0].data);
}
@@ -0,0 +1,54 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for touchscreen driver device irrelevance code.
*/
#ifndef TSD_COM_H
#define TSD_COM_H
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
extern void TSDCom_InterpolateMeasurement(
const uint32_t *pData,
uint32_t *pPoint);
uint8_t TSDCom_Calibrate(void);
uint8_t TSDCom_IsCalibrationOk(void);
void TSDCom_ReadCalibrateData(void *pBuffer, uint32_t size);
void TSDCom_RestoreCalibrateData(void *pBuffer, uint32_t size);
#endif /* #ifndef TSD_COM_H */
+377
View File
@@ -0,0 +1,377 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup twi_module Working with TWI
* The TWI driver provides the interface to configure and use the TWI
* peripheral.
*
* \usage
* <ul>
* <li> Configures a TWI peripheral to operate in master mode, at the given
* frequency (in Hz) using TWI_Configure(). </li>
* <li> Sends a STOP condition on the TWI using TWI_Stop().</li>
* <li> Starts a read operation on the TWI bus with the specified slave using
* TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever
* a byte is available (poll using TWI_ByteReceived()).</li>
* <li> Starts a write operation on the TWI to access the selected slave using
* TWI_StartWrite(). A byte of data must be provided to start the write;
* other bytes are written next.</li>
* <li> Sends a byte of data to one of the TWI slaves on the bus using TWI_WriteByte().
* This function must be called once before TWI_StartWrite() with the first byte of data
* to send, then it shall be called repeatedly after that to send the remaining bytes.</li>
* <li> Check if a byte has been received and can be read on the given TWI
* peripheral using TWI_ByteReceived().<
* Check if a byte has been sent using TWI_ByteSent().</li>
* <li> Check if the current transmission is complete (the STOP has been sent)
* using TWI_TransferComplete().</li>
* <li> Enables & disable the selected interrupts sources on a TWI peripheral
* using TWI_EnableIt() and TWI_DisableIt().</li>
* <li> Get current status register of the given TWI peripheral using
* TWI_GetStatus(). Get current status register of the given TWI peripheral, but
* masking interrupt sources which are not currently enabled using
* TWI_GetMaskedStatus().</li>
* </ul>
* For more accurate information, please look at the TWI section of the
* Datasheet.
*
* Related files :\n
* \ref twi.c\n
* \ref twi.h.\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Two Wire Interface (TWI).
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include "twi.h"
#include <utility/math.h>
#include <utility/assert.h>
#include <utility/trace.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Configures a TWI peripheral to operate in master mode, at the given
* frequency (in Hz). The duty cycle of the TWI clock is set to 50%.
* \param pTwi Pointer to an Twi instance.
* \param twck Desired TWI clock frequency.
* \param mck Master clock frequency.
*/
void TWI_ConfigureMaster(Twi *pTwi, uint32_t twck, uint32_t mck)
{
uint32_t ckdiv = 0;
uint32_t cldiv;
uint8_t ok = 0;
TRACE_DEBUG("TWI_ConfigureMaster()\n\r");
SANITY_CHECK(pTwi);
/* SVEN: TWI Slave Mode Enabled */
pTwi->TWI_CR = TWI_CR_SVEN;
/* Reset the TWI*/
pTwi->TWI_CR = TWI_CR_SWRST;
pTwi->TWI_RHR;
/* TWI Slave Mode Disabled, TWI Master Mode Disabled. */
pTwi->TWI_CR = TWI_CR_SVDIS;
pTwi->TWI_CR = TWI_CR_MSDIS;
/* Set master mode */
pTwi->TWI_CR = TWI_CR_MSEN;
/* Configure clock */
while (!ok) {
cldiv = ((mck / (2 * twck)) - 3) / power(2, ckdiv);
if (cldiv <= 255) {
ok = 1;
}
else {
ckdiv++;
}
}
ASSERT(ckdiv < 8, "-F- Cannot find valid TWI clock parameters\n\r");
TRACE_DEBUG("Using CKDIV = %u and CLDIV/CHDIV = %u\n\r", ckdiv, cldiv);
pTwi->TWI_CWGR = 0;
pTwi->TWI_CWGR = (ckdiv << 16) | (cldiv << 8) | cldiv;
}
/**
* \brief Configures a TWI peripheral to operate in slave mode.
* \param pTwi Pointer to an Twi instance.
* \param slaveAddress Slave address.
*/
void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress)
{
uint32_t i;
/* TWI software reset */
pTwi->TWI_CR = TWI_CR_SWRST;
pTwi->TWI_RHR;
/* Wait at least 10 ms */
for (i=0; i < 1000000; i++);
/* TWI Slave Mode Disabled, TWI Master Mode Disabled*/
pTwi->TWI_CR = TWI_CR_SVDIS | TWI_CR_MSDIS;
/* Configure slave address. */
pTwi->TWI_SMR = 0;
pTwi->TWI_SMR = (slaveAddress << 16) & TWI_SMR_SADR;
/* SVEN: TWI Slave Mode Enabled */
pTwi->TWI_CR = TWI_CR_SVEN;
/* Wait at least 10 ms */
for (i=0; i < 1000000; i++);
ASSERT( (pTwi->TWI_CR & TWI_CR_SVDIS)!= TWI_CR_SVDIS, "Can't configure TWI slave mode");
}
/**
* \brief Sends a STOP condition on the TWI.
* \param pTwi Pointer to an Twi instance.
*/
void TWI_Stop(Twi *pTwi)
{
SANITY_CHECK(pTwi);
pTwi->TWI_CR = TWI_CR_STOP;
}
/**
* \brief Starts a read operation on the TWI bus with the specified slave, it returns
* immediately. Data must then be read using TWI_ReadByte() whenever a byte is
* available (poll using TWI_ByteReceived()).
* \param pTwi Pointer to an Twi instance.
* \param address Slave address on the bus.
* \param iaddress Optional internal address bytes.
* \param isize Number of internal address bytes.
*/
void TWI_StartRead(
Twi *pTwi,
uint8_t address,
uint32_t iaddress,
uint8_t isize)
{
SANITY_CHECK(pTwi);
SANITY_CHECK((address & 0x80) == 0);
SANITY_CHECK((iaddress & 0xFF000000) == 0);
SANITY_CHECK(isize < 4);
/* Set slave address and number of internal address bytes. */
pTwi->TWI_MMR = 0;
pTwi->TWI_MMR = (isize << 8) | TWI_MMR_MREAD | (address << 16);
/* Set internal address bytes */
pTwi->TWI_IADR = 0;
pTwi->TWI_IADR = iaddress;
/* Send START condition */
pTwi->TWI_CR = TWI_CR_START;
}
/**
* \brief Reads a byte from the TWI bus. The read operation must have been started
* using TWI_StartRead() and a byte must be available (check with TWI_ByteReceived()).
* \param pTwi Pointer to an Twi instance.
* \return byte read.
*/
uint8_t TWI_ReadByte(Twi *pTwi)
{
SANITY_CHECK(pTwi);
return pTwi->TWI_RHR;
}
/**
* \brief Sends a byte of data to one of the TWI slaves on the bus.
* \note This function must be called once before TWI_StartWrite() with
* the first byte of data to send, then it shall be called repeatedly
* after that to send the remaining bytes.
* \param pTwi Pointer to an Twi instance.
* \param byte Byte to send.
*/
void TWI_WriteByte(Twi *pTwi, uint8_t byte)
{
SANITY_CHECK(pTwi);
pTwi->TWI_THR = byte;
}
/**
* \brief Starts a write operation on the TWI to access the selected slave, then
* returns immediately. A byte of data must be provided to start the write;
* other bytes are written next.
* after that to send the remaining bytes.
* \param pTwi Pointer to an Twi instance.
* \param address Address of slave to acccess on the bus.
* \param iaddress Optional slave internal address.
* \param isize Number of internal address bytes.
* \param byte First byte to send.
*/
void TWI_StartWrite(
Twi *pTwi,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t byte)
{
SANITY_CHECK(pTwi);
SANITY_CHECK((address & 0x80) == 0);
SANITY_CHECK((iaddress & 0xFF000000) == 0);
SANITY_CHECK(isize < 4);
/* Set slave address and number of internal address bytes. */
pTwi->TWI_MMR = 0;
pTwi->TWI_MMR = (isize << 8) | (address << 16);
/* Set internal address bytes. */
pTwi->TWI_IADR = 0;
pTwi->TWI_IADR = iaddress;
/* Write first byte to send.*/
TWI_WriteByte(pTwi, byte);
}
/**
* \brief Check if a byte have been receiced from TWI.
* \param pTwi Pointer to an Twi instance.
* \return 1 if a byte has been received and can be read on the given TWI
* peripheral; otherwise, returns 0. This function resets the status register.
*/
uint8_t TWI_ByteReceived(Twi *pTwi)
{
return ((pTwi->TWI_SR & TWI_SR_RXRDY) == TWI_SR_RXRDY);
}
/**
* \brief Check if a byte have been sent to TWI.
* \param pTwi Pointer to an Twi instance.
* \return 1 if a byte has been sent so another one can be stored for
* transmission; otherwise returns 0. This function clears the status register.
*/
uint8_t TWI_ByteSent(Twi *pTwi)
{
return ((pTwi->TWI_SR & TWI_SR_TXRDY) == TWI_SR_TXRDY);
}
/**
* \brief Check if current transmission is complet.
* \param pTwi Pointer to an Twi instance.
* \return 1 if the current transmission is complete (the STOP has been sent);
* otherwise returns 0.
*/
uint8_t TWI_TransferComplete(Twi *pTwi)
{
return ((pTwi->TWI_SR & TWI_SR_TXCOMP) == TWI_SR_TXCOMP);
}
/**
* \brief Enables the selected interrupts sources on a TWI peripheral.
* \param pTwi Pointer to an Twi instance.
* \param sources Bitwise OR of selected interrupt sources.
*/
void TWI_EnableIt(Twi *pTwi, uint32_t sources)
{
SANITY_CHECK(pTwi);
SANITY_CHECK((sources & 0xFFFFF088) == 0);
pTwi->TWI_IER = sources;
}
/**
* \brief Disables the selected interrupts sources on a TWI peripheral.
* \param pTwi Pointer to an Twi instance.
* \param sources Bitwise OR of selected interrupt sources.
*/
void TWI_DisableIt(Twi *pTwi, uint32_t sources)
{
SANITY_CHECK(pTwi);
SANITY_CHECK((sources & 0xFFFFF088) == 0);
pTwi->TWI_IDR = sources;
}
/**
* \brief Get the current status register of the given TWI peripheral.
* \note This resets the internal value of the status register, so further
* read may yield different values.
* \param pTwi Pointer to an Twi instance.
* \return TWI status register.
*/
uint32_t TWI_GetStatus(Twi *pTwi)
{
SANITY_CHECK(pTwi);
return pTwi->TWI_SR;
}
/**
* \brief Returns the current status register of the given TWI peripheral, but
* masking interrupt sources which are not currently enabled.
* \note This resets the internal value of the status register, so further
* read may yield different values.
* \param pTwi Pointer to an Twi instance.
*/
uint32_t TWI_GetMaskedStatus(Twi *pTwi)
{
uint32_t status;
SANITY_CHECK(pTwi);
status = pTwi->TWI_SR;
status &= pTwi->TWI_IMR;
return status;
}
/**
* \brief Sends a STOP condition. STOP Condition is sent just after completing
* the current byte transmission in master read mode.
* \param pTwi Pointer to an Twi instance.
*/
void TWI_SendSTOPCondition(Twi *pTwi)
{
SANITY_CHECK(pTwi);
pTwi->TWI_CR |= TWI_CR_STOP;
}
+95
View File
@@ -0,0 +1,95 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Interface for configuration the Two Wire Interface (TWI) peripheral.
*
*/
#ifndef TWI_H
#define TWI_H
/*----------------------------------------------------------------------------
* Macros
*----------------------------------------------------------------------------*/
/* Returns 1 if the TXRDY bit (ready to transmit data) is set in the given status register value.*/
#define TWI_STATUS_TXRDY(status) ((status & TWI_SR_TXRDY) == TWI_SR_TXRDY)
/* Returns 1 if the RXRDY bit (ready to receive data) is set in the given status register value.*/
#define TWI_STATUS_RXRDY(status) ((status & TWI_SR_RXRDY) == TWI_SR_RXRDY)
/* Returns 1 if the TXCOMP bit (transfer complete) is set in the given status register value.*/
#define TWI_STATUS_TXCOMP(status) ((status & TWI_SR_TXCOMP) == TWI_SR_TXCOMP)
/*----------------------------------------------------------------------------
* External function
*----------------------------------------------------------------------------*/
extern void TWI_ConfigureMaster(Twi *pTwi, uint32_t twck, uint32_t mck);
extern void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress);
extern void TWI_Stop(Twi *pTwi);
extern void TWI_StartRead(
Twi *pTwi,
uint8_t address,
uint32_t iaddress,
uint8_t isize);
extern uint8_t TWI_ReadByte(Twi *pTwi);
extern void TWI_WriteByte(Twi *pTwi, uint8_t byte);
extern void TWI_StartWrite(
Twi *pTwi,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t byte);
extern uint8_t TWI_ByteReceived(Twi *pTwi);
extern uint8_t TWI_ByteSent(Twi *pTwi);
extern uint8_t TWI_TransferComplete(Twi *pTwi);
extern void TWI_EnableIt(Twi *pTwi, uint32_t sources);
extern void TWI_DisableIt(Twi *pTwi, uint32_t sources);
extern uint32_t TWI_GetStatus(Twi *pTwi);
extern uint32_t TWI_GetMaskedStatus(Twi *pTwi);
extern void TWI_SendSTOPCondition(Twi *pTwi);
#endif //#ifndef TWI_H
+342
View File
@@ -0,0 +1,342 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "twid.h"
#include <twi/twi.h>
#include <utility/assert.h>
#include <utility/trace.h>
/*----------------------------------------------------------------------------
* Definition
*----------------------------------------------------------------------------*/
#define TWITIMEOUTMAX 50000
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** TWI driver callback function.*/
typedef void (*TwiCallback)(Async *);
/** TWI asynchronous transfer descriptor.*/
typedef struct _AsyncTwi {
/** Asynchronous transfer status. */
volatile uint8_t status;
// Callback function to invoke when transfer completes or fails.*/
TwiCallback callback;
/** Pointer to the data buffer.*/
uint8_t *pData;
/** Total number of bytes to transfer.*/
uint32_t num;
/** Number of already transferred bytes.*/
uint32_t transferred;
} AsyncTwi;
/*----------------------------------------------------------------------------
* Global functions
*----------------------------------------------------------------------------*/
/**
* \brief Initializes a TWI driver instance, using the given TWI peripheral.
* \note The peripheral must have been initialized properly before calling this function.
* \param pTwid Pointer to the Twid instance to initialize.
* \param pTwi Pointer to the TWI peripheral to use.
*/
void TWID_Initialize(Twid *pTwid, Twi *pTwi)
{
TRACE_DEBUG("TWID_Initialize()\n\r");
SANITY_CHECK(pTwid);
SANITY_CHECK(pTwi);
/* Initialize driver. */
pTwid->pTwi = pTwi;
pTwid->pTransfer = 0;
}
/**
* \brief Interrupt handler for a TWI peripheral. Manages asynchronous transfer
* occuring on the bus. This function MUST be called by the interrupt service
* routine of the TWI peripheral if asynchronous read/write are needed.
* \param pTwid Pointer to a Twid instance.
*/
void TWID_Handler(Twid *pTwid)
{
uint8_t status;
AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
Twi *pTwi = pTwid->pTwi;
SANITY_CHECK(pTwid);
/* Retrieve interrupt status */
status = TWI_GetMaskedStatus(pTwi);
/* Byte received */
if (TWI_STATUS_RXRDY(status)) {
pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi);
pTransfer->transferred++;
/* check for transfer finish */
if (pTransfer->transferred == pTransfer->num) {
TWI_DisableIt(pTwi, TWI_IDR_RXRDY);
TWI_EnableIt(pTwi, TWI_IER_TXCOMP);
}
/* Last byte? */
else if (pTransfer->transferred == (pTransfer->num - 1)) {
TWI_Stop(pTwi);
}
}
/* Byte sent*/
else if (TWI_STATUS_TXRDY(status)) {
/* Transfer finished ? */
if (pTransfer->transferred == pTransfer->num) {
TWI_DisableIt(pTwi, TWI_IDR_TXRDY);
TWI_EnableIt(pTwi, TWI_IER_TXCOMP);
TWI_SendSTOPCondition(pTwi);
}
/* Bytes remaining */
else {
TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]);
pTransfer->transferred++;
}
}
/* Transfer complete*/
else if (TWI_STATUS_TXCOMP(status)) {
TWI_DisableIt(pTwi, TWI_IDR_TXCOMP);
pTransfer->status = 0;
if (pTransfer->callback) {
pTransfer->callback((Async *) pTransfer);
}
pTwid->pTransfer = 0;
}
}
/**
* \brief Asynchronously reads data from a slave on the TWI bus. An optional
* callback function is triggered when the transfer is complete.
* \param pTwid Pointer to a Twid instance.
* \param address TWI slave address.
* \param iaddress Optional slave internal address.
* \param isize Internal address size in bytes.
* \param pData Data buffer for storing received bytes.
* \param num Number of bytes to read.
* \param pAsync Asynchronous transfer descriptor.
* \return 0 if the transfer has been started; otherwise returns a TWI error code.
*/
uint8_t TWID_Read(
Twid *pTwid,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t *pData,
uint32_t num,
Async *pAsync)
{
Twi *pTwi = pTwid->pTwi;
AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
uint32_t timeout;
SANITY_CHECK(pTwid);
SANITY_CHECK((address & 0x80) == 0);
SANITY_CHECK((iaddress & 0xFF000000) == 0);
SANITY_CHECK(isize < 4);
/* Check that no transfer is already pending*/
if (pTransfer) {
TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
return TWID_ERROR_BUSY;
}
/* Set STOP signal if only one byte is sent*/
if (num == 1) {
TWI_Stop(pTwi);
}
/* Asynchronous transfer*/
if (pAsync) {
/* Update the transfer descriptor */
pTwid->pTransfer = pAsync;
pTransfer = (AsyncTwi *) pAsync;
pTransfer->status = ASYNC_STATUS_PENDING;
pTransfer->pData = pData;
pTransfer->num = num;
pTransfer->transferred = 0;
/* Enable read interrupt and start the transfer */
TWI_EnableIt(pTwi, TWI_IER_RXRDY);
TWI_StartRead(pTwi, address, iaddress, isize);
}
/* Synchronous transfer*/
else {
/* Start read*/
TWI_StartRead(pTwi, address, iaddress, isize);
/* Read all bytes, setting STOP before the last byte*/
while (num > 0) {
/* Last byte ?*/
if (num == 1) {
TWI_Stop(pTwi);
}
/* Wait for byte then read and store it*/
timeout = 0;
while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) );
if (timeout == TWITIMEOUTMAX) {
TRACE_ERROR("TWID Timeout BR\n\r");
}
*pData++ = TWI_ReadByte(pTwi);
num--;
}
/* Wait for transfer to be complete */
timeout = 0;
while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
if (timeout == TWITIMEOUTMAX) {
TRACE_ERROR("TWID Timeout TC\n\r");
}
}
return 0;
}
/**
* \brief Asynchronously sends data to a slave on the TWI bus. An optional callback
* function is invoked whenever the transfer is complete.
* \param pTwid Pointer to a Twid instance.
* \param address TWI slave address.
* \param iaddress Optional slave internal address.
* \param isize Number of internal address bytes.
* \param pData Data buffer for storing received bytes.
* \param num Data buffer to send.
* \param pAsync Asynchronous transfer descriptor.
* \return 0 if the transfer has been started; otherwise returns a TWI error code.
*/
uint8_t TWID_Write(
Twid *pTwid,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t *pData,
uint32_t num,
Async *pAsync)
{
Twi *pTwi = pTwid->pTwi;
AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
uint32_t timeout;
SANITY_CHECK(pTwi);
SANITY_CHECK((address & 0x80) == 0);
SANITY_CHECK((iaddress & 0xFF000000) == 0);
SANITY_CHECK(isize < 4);
/* Check that no transfer is already pending */
if (pTransfer) {
TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
return TWID_ERROR_BUSY;
}
/* Asynchronous transfer */
if (pAsync) {
/* Update the transfer descriptor */
pTwid->pTransfer = pAsync;
pTransfer = (AsyncTwi *) pAsync;
pTransfer->status = ASYNC_STATUS_PENDING;
pTransfer->pData = pData;
pTransfer->num = num;
pTransfer->transferred = 1;
/* Enable write interrupt and start the transfer */
TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
TWI_EnableIt(pTwi, TWI_IER_TXRDY);
}
/* Synchronous transfer*/
else {
// Start write
TWI_StartWrite(pTwi, address, iaddress, isize, *pData++);
num--;
/* Send all bytes */
while (num > 0) {
/* Wait before sending the next byte */
timeout = 0;
while( !TWI_ByteSent(pTwi) && (++timeout<TWITIMEOUTMAX) );
if (timeout == TWITIMEOUTMAX) {
TRACE_ERROR("TWID Timeout BS\n\r");
}
TWI_WriteByte(pTwi, *pData++);
num--;
}
/* Wait for actual end of transfer */
timeout = 0;
#ifdef TWI_V3XX
/* Send a STOP condition */
TWI_SendSTOPCondition(pTwi);
#endif
while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
if (timeout == TWITIMEOUTMAX) {
TRACE_ERROR("TWID Timeout TC2\n\r");
}
}
return 0;
}
+86
View File
@@ -0,0 +1,86 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
#ifndef TWID_H
#define TWID_H
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <board.h>
#include <drivers/async/async.h>
/*----------------------------------------------------------------------------
* Definition
*----------------------------------------------------------------------------*/
/** TWI driver is currently busy. */
#define TWID_ERROR_BUSY 1
/*----------------------------------------------------------------------------
* Types
*----------------------------------------------------------------------------*/
/** TWI driver structure. Holds the internal state of the driver.*/
typedef struct _Twid {
/** Pointer to the underlying TWI peripheral.*/
Twi *pTwi;
/** Current asynchronous transfer being processed.*/
Async *pTransfer;
} Twid;
/*----------------------------------------------------------------------------
* Export functions
*----------------------------------------------------------------------------*/
extern void TWID_Initialize(Twid *pTwid, Twi *pTwi);
extern void TWID_Handler(Twid *pTwid);
extern uint8_t TWID_Read(
Twid *pTwid,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t *pData,
uint32_t num,
Async *pAsync);
extern uint8_t TWID_Write(
Twid *pTwid,
uint8_t address,
uint32_t iaddress,
uint8_t isize,
uint8_t *pData,
uint32_t num,
Async *pAsync);
#endif //#ifndef TWID_H
@@ -0,0 +1,288 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implements UART console.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <board.h>
#include <pio/pio.h>
#include <pmc/pmc.h>
#include "usart/uart_console.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Console baudrate always using 115200. */
#define CONSOLE_BAUDRATE 115200
/** Usart Hw interface used by the console (UART0). */
#define CONSOLE_USART UART0
/** Usart Hw ID used by the console (UART0). */
#define CONSOLE_ID ID_UART0
/** Pins description corresponding to Rxd,Txd, (UART pins) */
#define CONSOLE_PINS {PINS_UART}
/*----------------------------------------------------------------------------
* Variables
*----------------------------------------------------------------------------*/
/** Is Console Initialized. */
static uint8_t isConsolInitialized = 0;
/**
* \brief Configures an USART peripheral with the specified parameters.
*
* \param baudrate Baudrate at which the USART should operate (in Hz).
* \param masterClock Frequency of the system master clock (in Hz).
*/
static void UART_Configure( uint32_t baudrate,
uint32_t masterClock)
{
const Pin pPins[] = CONSOLE_PINS;
Uart *pUart = CONSOLE_USART;
/* Configure PIO */
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
/* Configure PMC */
PMC->PMC_PCER0 = 1 << CONSOLE_ID;
/* Reset and disable receiver & transmitter */
pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
| UART_CR_RXDIS | UART_CR_TXDIS;
/* Configure mode */
pUart->UART_MR = (0x4 << 9); /* TODO: Change with new symbols: AT91C_UART_CHRL_8_BITS | AT91C_UART_PAR_NONE */
/* Configure baudrate */
/* Asynchronous, no oversampling */
pUart->UART_BRGR = (masterClock / baudrate) / 16;
/* Disable PDC channel */
pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
/* Enable receiver and transmitter */
pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
isConsolInitialized = 1;
}
/**
* \brief Outputs a character on the UART line.
*
* \note This function is synchronous (i.e. uses polling).
* \param c Character to send.
*/
void UART_PutChar(uint8_t c)
{
Uart *pUart = CONSOLE_USART;
if (!isConsolInitialized)
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
/* Wait for the transmitter to be ready */
while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
/* Send character */
pUart->UART_THR = c;
}
/**
* \brief Input a character from the UART line.
*
* \note This function is synchronous
* \return character received.
*/
uint8_t UART_GetChar(void)
{
Uart *pUart = CONSOLE_USART;
if (!isConsolInitialized)
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
while((pUart->UART_SR & UART_SR_RXRDY) == 0);
return pUart->UART_RHR;
}
/**
* \brief Check if there is Input from UART line.
*
* \return true if there is Input.
*/
bool UART_IsRxReady(void)
{
Uart *pUart = CONSOLE_USART;
if (!isConsolInitialized)
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
return (pUart->UART_SR & UART_SR_RXRDY) > 0;
}
/* \cond NOFPUT */
#ifndef NOFPUT
#include <stdio.h>
#include <stdarg.h>
/**
* \brief Implementation of fputc using the UART as the standard output. Required
* for printf().
*
* \param c Character to write.
* \param pStream Output stream.
*
* \return The character written if successful, or -1 if the output stream is
* not stdout or stderr.
*/
int fputc ( int c, FILE * pStream )
{
if ((pStream == stdout) || (pStream == stderr)) {
UART_PutChar(c);
return c;
}
else {
return EOF;
}
}
/**
* \brief Implementation of fputs using the UART as the standard output. Required
* for printf(). Does NOT currently use the PDC.
*
* \param pStr String to write.
* \param pStream Output stream.
*
* \return Number of characters written if successful, or -1 if the output
* stream is not stdout or stderr.
*/
signed int fputs(const char *pStr, FILE *pStream)
{
signed int num = 0;
while (*pStr != 0) {
if (fputc(*pStr, pStream) == -1) {
return -1;
}
num++;
pStr++;
}
return num;
}
#undef putchar
/**
* \brief Outputs a character on the UART.
*
* \param c Character to output.
*
* \return The character that was output.
*/
signed int putchar(signed int c)
{
return fputc(c, stdout);
}
/* The char which has been ungotten, or EOF. */
static int _UngetChar = EOF;
/**
* \brief Implementation of fputc using the UART as the standard output. Required
* for printf().
*
* \param c Character to write.
* \param pStream Output stream.
*
* \return The character written if successful, or -1 if the output stream is
* not stdout or stderr.
*/
int fgetc (FILE * pStream )
{
int c;
if (pStream == stdin) {
c = UART_GetChar();
return c;
}
else {
return EOF;
}
}
#undef getchar
/**
* \brief Get a character from UART.
*
* \return The character received.
*/
signed int getchar(void)
{
if (_UngetChar != EOF)
{
int res = _UngetChar;
_UngetChar = EOF;
return res;
}
else
{
return fgetc(stdin);
}
}
#undef __ungetchar
/**
* \brief Unget a character from stdin.
*
* \return The unget character.
*/
signed int __ungetchar(int c)
{
_UngetChar = c;
return c;
}
#endif /* #ifndef NOFPUT */
/* \endcond */
@@ -0,0 +1,38 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
#ifndef UART_CONSOLE_H_
#define UART_CONSOLE_H_
extern void UART_PutChar(uint8_t c);
extern uint8_t UART_GetChar(void);
extern bool UART_IsRxReady(void);
#endif /* UART_CONSOLE_H_ */
+395
View File
@@ -0,0 +1,395 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup usart_module Working with USART
* The USART driver provides the interface to configure and use the USART peripheral.\n
*
* The USART supports several kinds of comminication modes such as full-duplex asynchronous/
* synchronous serial commnunication,RS485 with driver control signal,ISO7816,SPI and Test modes.
*
* To start a USART transfer with \ref AT91SAM3S_PDC "PDC" support, the user could follow these steps:
* <ul>
* <li> Configure USART with expected mode and baudrate(see \ref USART_Configure), which could be done by:
* -# Resetting and disabling transmitter and receiver by setting US_CR(Control Register). </li>
* -# Conifguring the USART in a specific mode by setting USART_MODE bits in US_MR(Mode Register) </li>
* -# Setting baudrate which is different from mode to mode.
</li>
* <li> Enable transmitter or receiver respectively by set US_CR_TXEN or US_CR_RXEN in US_CR.</li>
* <li> Read from or write to the peripheral with \ref USART_ReadBuffer or \ref USART_WriteBuffer.
These operations could be done by polling or interruption. </li>
* <li> For polling, check the status bit US_CSR_ENDRX/US_CSR_RXBUFF (READ) or US_CSR_ENDTX/
US_CSR_TXBUFE (WRITE). </li>
* <li> For interruption,"enable" the status bit through US_IER and
realize the hanler with USARTx_IrqHandler according to IRQ vector
table which is defined in board_cstartup_<toolchain>.c
To enable the interruption of USART,it should be configured with priority and enabled first through
NVIC .</li>
* </ul>
*
* For more accurate information, please look at the USART section of the
* Datasheet.
*
* Related files :\n
* \ref usart.c\n
* \ref usart.h\n
*/
/**
* \file
*
* Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)
* controller.
*
*/
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include <stdint.h>
#include "usart.h"
#include <utility/trace.h>
#include <utility/assert.h>
/*----------------------------------------------------------------------------
* Local definitions
*----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
/**
* \brief Configures an USART peripheral with the specified parameters.
*
*
* \param usart Pointer to the USART peripheral to configure.
* \param mode Desired value for the USART mode register (see the datasheet).
* \param baudrate Baudrate at which the USART should operate (in Hz).
* \param masterClock Frequency of the system master clock (in Hz).
*/
void USART_Configure(Usart *usart,
uint32_t mode,
uint32_t baudrate,
uint32_t masterClock)
{
/* Reset and disable receiver & transmitter*/
usart->US_CR = US_CR_RSTRX | US_CR_RSTTX
| US_CR_RXDIS | US_CR_TXDIS;
/* Configure mode*/
usart->US_MR = mode;
/* Configure baudrate*/
/* Asynchronous, no oversampling*/
if (((mode & US_MR_SYNC__CPHA) == 0)
&& ((mode & US_MR_OVER) == 0)) {
usart->US_BRGR = (masterClock / baudrate) / 16;
}
/* TODO other modes*/
}
/**
* \brief Enables or disables the transmitter of an USART peripheral.
*
*
* \param usart Pointer to an USART peripheral
* \param enabled If true, the transmitter is enabled; otherwise it is
* disabled.
*/
void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)
{
if (enabled) {
usart->US_CR = US_CR_TXEN;
}
else {
usart->US_CR = US_CR_TXDIS;
}
}
/**
* \brief Enables or disables the receiver of an USART peripheral
*
*
* \param usart Pointer to an USART peripheral
* \param enabled If true, the receiver is enabled; otherwise it is disabled.
*/
void USART_SetReceiverEnabled(Usart *usart,
uint8_t enabled)
{
if (enabled) {
usart->US_CR = US_CR_RXEN;
}
else {
usart->US_CR = US_CR_RXDIS;
}
}
/**
* \brief Sends one packet of data through the specified USART peripheral. This
* function operates synchronously, so it only returns when the data has been
* actually sent.
*
*
* \param usart Pointer to an USART peripheral.
* \param data Data to send including 9nth bit and sync field if necessary (in
* the same format as the US_THR register in the datasheet).
* \param timeOut Time out value (0 = no timeout).
*/
void USART_Write(
Usart *usart,
uint16_t data,
volatile uint32_t timeOut)
{
if (timeOut == 0) {
while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
}
else {
while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {
if (timeOut == 0) {
TRACE_ERROR("USART_Write: Timed out.\n\r");
return;
}
timeOut--;
}
}
usart->US_THR = data;
}
/**
* \brief Sends the contents of a data buffer through the specified USART peripheral.
* This function returns immediately (1 if the buffer has been queued, 0
* otherwise); poll the ENDTX and TXBUFE bits of the USART status register
* to check for the transfer completion.
*
* \param usart Pointer to an USART peripheral.
* \param buffer Pointer to the data buffer to send.
* \param size Size of the data buffer (in bytes).
*/
uint8_t USART_WriteBuffer(
Usart *usart,
void *buffer,
uint32_t size)
{
/* Check if the first PDC bank is free*/
if ((usart->US_TCR == 0) && (usart->US_TNCR == 0)) {
usart->US_TPR = (uint32_t) buffer;
usart->US_TCR = size;
usart->US_PTCR = US_PTCR_TXTEN;
return 1;
}
/* Check if the second PDC bank is free*/
else if (usart->US_TNCR == 0) {
usart->US_TNPR = (uint32_t) buffer;
usart->US_TNCR = size;
return 1;
}
else {
return 0;
}
}
/**
* \brief Reads and return a packet of data on the specified USART peripheral. This
* function operates asynchronously, so it waits until some data has been
* received.
*
* \param usart Pointer to an USART peripheral.
* \param timeOut Time out value (0 -> no timeout).
*/
uint16_t USART_Read(
Usart *usart,
volatile uint32_t timeOut)
{
if (timeOut == 0) {
while ((usart->US_CSR & US_CSR_RXRDY) == 0);
}
else {
while ((usart->US_CSR & US_CSR_RXRDY) == 0) {
if (timeOut == 0) {
TRACE_ERROR("USART_Read: Timed out.\n\r");
return 0;
}
timeOut--;
}
}
return usart->US_RHR;
}
/**
* \brief Reads data from an USART peripheral, filling the provided buffer until it
* becomes full. This function returns immediately with 1 if the buffer has
* been queued for transmission; otherwise 0.
*
* \param usart Pointer to an USART peripheral.
* \param buffer Pointer to the buffer where the received data will be stored.
* \param size Size of the data buffer (in bytes).
*/
uint8_t USART_ReadBuffer(Usart *usart,
void *buffer,
uint32_t size)
{
/* Check if the first PDC bank is free*/
if ((usart->US_RCR == 0) && (usart->US_RNCR == 0)) {
usart->US_RPR = (uint32_t) buffer;
usart->US_RCR = size;
usart->US_PTCR = US_PTCR_RXTEN;
return 1;
}
/* Check if the second PDC bank is free*/
else if (usart->US_RNCR == 0) {
usart->US_RNPR = (uint32_t) buffer;
usart->US_RNCR = size;
return 1;
}
else {
return 0;
}
}
/**
* \brief Returns 1 if some data has been received and can be read from an USART;
* otherwise returns 0.
*
* \param usart Pointer to an Usart instance.
*/
uint8_t USART_IsDataAvailable(Usart *usart)
{
if ((usart->US_CSR & US_CSR_RXRDY) != 0) {
return 1;
}
else {
return 0;
}
}
/**
* \brief Sets the filter value for the IRDA demodulator.
*
* \param pUsart Pointer to an Usart instance.
* \param filter Filter value.
*/
void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)
{
SANITY_CHECK(pUsart);
pUsart->US_IF = filter;
}
/**
* \brief Sends one packet of data through the specified USART peripheral. This
* function operates synchronously, so it only returns when the data has been
* actually sent.
*
* \param usart Pointer to an USART peripheral.
* \param c Character to send
*/
void USART_PutChar(
Usart *usart,
uint8_t c)
{
/* Wait for the transmitter to be ready*/
while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
/* Send character*/
usart->US_THR = c;
/* Wait for the transfer to complete*/
while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);
}
/**
* \brief Return 1 if a character can be read in USART
*/
uint32_t USART_IsRxReady(Usart *usart)
{
return (usart->US_CSR & US_CSR_RXRDY);
}
/**
* \brief Get present status
*/
uint32_t USART_GetStatus(Usart *usart)
{
return usart->US_CSR;
}
/**
* \brief Enable interrupt
*/
void USART_EnableIt(Usart *usart,uint32_t mode)
{
usart->US_IER = mode;
}
/**
* \brief Disable interrupt
*/
void USART_DisableIt(Usart *usart,uint32_t mode)
{
usart->US_IDR = mode;
}
/**
* \brief Reads and returns a character from the USART.
*
* \note This function is synchronous (i.e. uses polling).
* \param usart Pointer to an USART peripheral.
* \return Character received.
*/
uint8_t USART_GetChar(Usart *usart)
{
while ((usart->US_CSR & US_CSR_RXRDY) == 0);
return usart->US_RHR;
}
+129
View File
@@ -0,0 +1,129 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* \par Purpose
*
* This module provides several definitions and methods for using an USART
* peripheral.
*
* \par Usage
*
* -# Enable the USART peripheral clock in the PMC.
* -# Enable the required USART PIOs (see pio.h).
* -# Configure the UART by calling USART_Configure.
* -# Enable the transmitter and/or the receiver of the USART using
* USART_SetTransmitterEnabled and USART_SetReceiverEnabled.
* -# Send data through the USART using the USART_Write and
* USART_WriteBuffer methods.
* -# Receive data from the USART using the USART_Read and
* USART_ReadBuffer functions; the availability of data can be polled
* with USART_IsDataAvailable.
* -# Disable the transmitter and/or the receiver of the USART with
* USART_SetTransmitterEnabled and USART_SetReceiverEnabled.
*/
#ifndef USART_H
#define USART_H
/*------------------------------------------------------------------------------
* Headers
*------------------------------------------------------------------------------*/
#include <board.h>
/*------------------------------------------------------------------------------
* Definitions
*------------------------------------------------------------------------------*/
/** \section USART_mode USART modes
* This section lists several common operating modes for an USART peripheral.
*
* \b Modes
* - USART_MODE_ASYNCHRONOUS
* - USART_MODE_IRDA
*/
/** Basic asynchronous mode, i.e. 8 bits no parity.*/
#define USART_MODE_ASYNCHRONOUS (AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE)
/** IRDA mode*/
#define USART_MODE_IRDA (AT91C_US_USMODE_IRDA | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_FILTER)
/*------------------------------------------------------------------------------*/
/* Exported functions*/
/*------------------------------------------------------------------------------*/
extern void USART_Configure(
Usart *usart,
uint32_t mode,
uint32_t baudrate,
uint32_t masterClock);
extern uint32_t USART_GetStatus(Usart *usart);
extern void USART_EnableIt(Usart *usart,uint32_t mode);
extern void USART_DisableIt(Usart *usart,uint32_t mode);
extern void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled);
extern void USART_SetReceiverEnabled(Usart *usart, uint8_t enabled);
extern void USART_Write(
Usart *usart,
uint16_t data,
volatile uint32_t timeOut);
extern uint8_t USART_WriteBuffer(
Usart *usart,
void *buffer,
uint32_t size);
extern uint16_t USART_Read(
Usart *usart,
volatile uint32_t timeOut);
extern uint8_t USART_ReadBuffer(
Usart *usart,
void *buffer,
uint32_t size);
extern uint8_t USART_IsDataAvailable(Usart *usart);
extern void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter);
extern void USART_PutChar(Usart *usart, uint8_t c);
extern uint32_t USART_IsRxReady(Usart *usart);
extern uint8_t USART_GetChar(Usart *usart);
#endif /*#ifndef USART_H*/
@@ -0,0 +1,114 @@
/* ----------------------------------------------------------------------------
* 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 the ASSERT() and SANITY_CHECK() macros, which are used for
/// runtime condition & parameter verifying.
///
/// !Usage
///
/// -# Use ASSERT() in your code to check the value of function parameters,
/// return values, etc. *Warning:* the ASSERT() condition must not have
/// any side-effect; otherwise, the program may not work properly
/// anymore when assertions are disabled.
/// -# Use SANITY_CHECK() to perform checks with a default error message
/// (outputs the file and line number where the error occured). This
/// reduces memory overhead caused by assertion error strings.
/// -# Initialize the dbgu to see failed assertions at run-time.
/// -# Assertions can be entirely disabled by defining the NOASSERT symbol
/// at compilation time.
//------------------------------------------------------------------------------
#ifndef ASSERT_H
#define ASSERT_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <stdio.h>
#include "trace.h"
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
#if defined(NOASSERT)
#define ASSERT(...)
#define SANITY_CHECK(...)
#else
#if (TRACE_LEVEL == 0)
/// Checks that the given condition is true,
/// otherwise stops the program execution.
/// \param condition Condition to verify.
#define ASSERT(condition, ...) { \
if (!(condition)) { \
while (1); \
} \
}
/// Performs the same duty as the ASSERT() macro
/// \param condition Condition to verify.
#define SANITY_CHECK(condition) ASSERT(condition, ...)
#else
/// Checks that the given condition is true, otherwise displays an error
/// message and stops the program execution.
/// \param condition Condition to verify.
#define ASSERT(condition, ...) { \
if (!(condition)) { \
printf("-F- ASSERT: "); \
printf(__VA_ARGS__); \
while (1); \
} \
}
#define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
/// Performs the same duty as the ASSERT() macro, except a default error
/// message is output if the condition is false.
/// \param condition Condition to verify.
#define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
#endif
#endif
#endif //#ifndef ASSERT_H
@@ -0,0 +1,108 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, 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.
* ----------------------------------------------------------------------------
*/
#ifndef BITBANDING_H
#define BITBANDING_H
//------------------------------------------------------------------------------
/// \file bitbanding.h
/// Include Defines & macros for bit-banding.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Header files
//------------------------------------------------------------------------------
#include <stdint.h>
//------------------------------------------------------------------------------
// Global Macros
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// \def IS_BITBAND_SRAM_ADDR(x)
/// \brief Check if the address is in bit banding sram region.
/// \note The address should be in area of 0x2000000 ~ 0x200FFFFF
/// \param x The address to check.
//------------------------------------------------------------------------------
#define IS_BITBAND_SRAM_ADDR(x) \
( ((uint32_t)(x)) >= 0x20000000 && \
((uint32_t)(x)) < (0x20000000+0x100000) )
//------------------------------------------------------------------------------
/// \def IS_BITBAND_PERIPH_ADDR(x)
/// \brief Check if the address is in bit banding peripheral region
/// \note The address should be in area of 0x4000000 ~ 0x400FFFFF
/// \param x The address to check
//------------------------------------------------------------------------------
#define IS_BITBAND_PERIPH_ADDR(x) \
( ((uint32_t)(x)) >= 0x40000000 && \
((uint32_t)(x)) < (0x40000000+0x100000) )
//------------------------------------------------------------------------------
/// \def BITBAND_ALIAS_ADDRESS(addr, bit)
/// \brief Calculate bit band alias address.
///
/// Calculate the bit band alias address and return a pointer address to word.
/// \param addr The byte address of bitbanding bit.
/// \param bit The bit position of bitbanding bit.
/// \callergraph
//------------------------------------------------------------------------------
#define BITBAND_ALIAS_ADDRESS(addr, bit) \
((volatile uint32_t*)((((uint32_t)(addr) & 0xF0000000) + 0x02000000) \
+((((uint32_t)(addr)&0xFFFFF)*32)\
+( (uint32_t)(bit)*4))))
//------------------------------------------------------------------------------
/// \def WRITE_BITBANDING(addr32, bit, val)
/// \brief Bit write through bit banding.
/// \param addr32 32-bit aligned byte address where the bit exists.
/// \param bit Bit position.
/// \param val The value that the bit is set to.
/// \callergraph
//------------------------------------------------------------------------------
#define WRITE_BITBANDING(addr32, bit, val) do {\
*BITBAND_ALIAS_ADDRESS(addr32,bit) = (val); \
} while (0);
//------------------------------------------------------------------------------
/// \def TOGGLE_BITBANDING(addr32, bit)
/// \brief Toggle bit through bit banding
/// \param addr32 32-bit aligned byte address where the bit exists.
/// \param bit Bit position.
//------------------------------------------------------------------------------
#define TOGGLE_BITBANDING(addr32, bit) do {\
volatile uint32_t * p = \
BITBAND_ALIAS_ADDRESS(addr32,bit); \
if (*p) *p = 0; \
else *p = 1; \
}while(0);
#endif //#ifndef BITBANDING_H
+322
View File
@@ -0,0 +1,322 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "bmp.h"
#include <board.h>
#include <utility/trace.h>
#include <string.h>
//-----------------------------------------------------------------------------
// Define
//-----------------------------------------------------------------------------
/// BMP offset for header
#define IMAGE_OFFSET 0x100
//------------------------------------------------------------------------------
// Internal constants
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Internal types
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Describe the BMP palette
//------------------------------------------------------------------------------
struct BMPPaletteEntry {
/// Blue value
unsigned char b;
/// Green value
unsigned char g;
/// Red value
unsigned char r;
/// Filler character value
unsigned char filler;
};
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Test if BMP is valid
/// \param file Buffer holding the file to examinate.
/// \return 1 if the header of a BMP file is valid; otherwise returns 0.
//------------------------------------------------------------------------------
unsigned char BMP_IsValid(void *file)
{
return ((struct BMPHeader *) file)->type == BMP_TYPE;
}
//------------------------------------------------------------------------------
/// Returns the size of a BMP image given at least its header (the file does
/// not have to be complete).
/// \param file Pointer to the buffer which holds the BMP file.
/// \return size of BMP image
//------------------------------------------------------------------------------
unsigned int BMP_GetFileSize(void *file)
{
return ((struct BMPHeader *) file)->fileSize;
}
//-----------------------------------------------------------------------------
/// Write a BMP header
/// \param pAddressHeader Begin address of the BMP
/// \param bmpHSize BMP heigth size
/// \param bmpVSize BMP width size
/// \param bmpRgb Type of BMP (YUV or RGB)
/// \param nbByte_Pixels Number of byte per pixels
//-----------------------------------------------------------------------------
void WriteBMPheader(unsigned int* pAddressHeader,
unsigned int bmpHSize,
unsigned int bmpVSize,
unsigned char bmpRgb,
unsigned char nbByte_Pixels)
{
unsigned int i;
unsigned int* fill;
struct BMPHeader *Header;
fill = pAddressHeader;
for (i=0; i<IMAGE_OFFSET; i+=4) {
*fill++ = 0;
}
Header = (struct BMPHeader*) pAddressHeader;
Header->type = BMP_TYPE;
Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
Header->reserved1 = 0;
Header->reserved2 = 0;
Header->offset = IMAGE_OFFSET;
Header->headerSize = BITMAPINFOHEADER;
Header->width = bmpHSize;
Header->height = bmpVSize;
Header->planes = 1;
Header->bits = nbByte_Pixels * 8;
Header->compression = 0;
Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
Header->xresolution = 0;
Header->yresolution = 0;
Header->ncolours = 0;
Header->importantcolours = 0;
}
//------------------------------------------------------------------------------
/// debug function, dislay BMP header
/// \param pAddressHeader Address of the BMP
//------------------------------------------------------------------------------
void BMP_displayHeader(unsigned int* pAddressHeader)
{
struct BMPHeader *header;
header = (struct BMPHeader*) pAddressHeader;
TRACE_INFO("BMP\n\r");
TRACE_INFO("type 0x%X \n\r", header->type);
TRACE_INFO("fileSize %d \n\r", header->fileSize);
TRACE_INFO("reserved1 %d \n\r", header->reserved1);
TRACE_INFO("reserved2 %d \n\r", header->reserved2);
TRACE_INFO("offset %d \n\r", header->offset);
TRACE_INFO("headerSize %d \n\r", header->headerSize);
TRACE_INFO("width %d \n\r", header->width);
TRACE_INFO("height %d \n\r", header->height);
TRACE_INFO("planes %d \n\r", header->planes);
TRACE_INFO("bits %d \n\r", header->bits);
TRACE_INFO("compression %d \n\r", header->compression);
TRACE_INFO("imageSize %d \n\r", header->imageSize);
TRACE_INFO("xresolution %d \n\r", header->xresolution);
TRACE_INFO("yresolution %d \n\r", header->yresolution);
TRACE_INFO("ncolours %d \n\r", header->ncolours);
TRACE_INFO("importantcolours %d\n\r", header->importantcolours);
}
//------------------------------------------------------------------------------
/// Loads a BMP image located at the given address, decodes it and stores the
/// resulting image inside the provided buffer. Image must have the specified
/// width & height.
/// If no buffer is provided, this function simply checks if it is able to
/// decode the image.
/// \param file Buffer which holds the BMP file.
/// \param buffer Buffer in which to store the decoded image.
/// \param width Buffer width in pixels.
/// \param height Buffer height in pixels.
/// \param bpp Number of bits per pixels that the buffer stores.
/// \return 0 if the image has been loaded; otherwise returns an error code.
//------------------------------------------------------------------------------
unsigned char BMP_Decode(
void *file,
unsigned char *buffer,
unsigned int width,
unsigned int height,
unsigned char bpp)
{
struct BMPHeader *header;
unsigned int i, j;
unsigned char r, g, b;
unsigned char *image;
// Read header information
header = (struct BMPHeader *) file;
// Verify that the file is valid
if (!BMP_IsValid(file)) {
TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
return 1;
}
// Check that parameters match
if ((header->compression != 0)
|| (header->width != width)
|| (header->height != height)) {
TRACE_ERROR("BMP_Decode: File format not supported\n\r");
TRACE_ERROR(" -> .compression = %u\n\r", header->compression);
TRACE_ERROR(" -> .width = %u\n\r", header->width);
TRACE_ERROR(" -> .height = %u\n\r", header->height);
TRACE_ERROR(" -> .bits = %d\n\r", header->bits);
return 2;
}
// Get image data
image = (unsigned char *) ((unsigned int) file + header->offset);
// Check that the bpp resolution is supported
// Only a 24-bit output & 24- or 8-bit input are supported
if (bpp != 24) {
TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
return 3;
}
else if (header->bits == 24) {
// Decoding is ok
if (!buffer) return 0;
// Get image data (swapping red & blue)
for (i=0; i < height; i++) {
for (j=0; j < width; j++) {
r = image[((height - i - 1) * width + j) * 3 + 2];
g = image[((height - i - 1) * width + j) * 3 + 1];
b = image[((height - i - 1) * width + j) * 3];
#if defined(BOARD_LCD_RGB565)
// Interlacing
r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
g = (g << 1) & 0xF8;
b = b & 0xF8;
buffer[(i * width + j) * 3] = b;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = r;
#else
buffer[(i * width + j) * 3] = r;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = b;
#endif //#if defined(BOARD_LCD_RGB565)
}
}
}
else if (header->bits == 8) {
// Decoding is ok
if (!buffer) return 0;
// Retrieve palette
struct BMPPaletteEntry palette[256];
memcpy(palette,
(unsigned char *) ((unsigned int) file + sizeof(struct BMPHeader)),
header->offset - sizeof(struct BMPHeader));
// Decode image (reversing row order)
for (i=0; i < height; i++) {
for (j=0; j < width; j++) {
r = palette[image[(height - i - 1) * width + j]].r;
g = palette[image[(height - i - 1) * width + j]].g;
b = palette[image[(height - i - 1) * width + j]].b;
buffer[(i * width + j) * 3] = r;
buffer[(i * width + j) * 3 + 1] = g;
buffer[(i * width + j) * 3 + 2] = b;
}
}
}
else {
TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
TRACE_INFO("header->bits 0x%X \n\r", header->bits);
return 4;
}
return 0;
}
//------------------------------------------------------------------------------
/// Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
/// \param fileSource Buffer which holds the RGB file
/// \param fileDestination Buffer in which to store the decoded image
/// \param width Buffer width in pixels.
/// \param height Buffer height in pixels.
/// \param bpp Number of bits per pixels that the buffer stores.
//------------------------------------------------------------------------------
void RGB565toBGR555(
unsigned char *fileSource,
unsigned char *fileDestination,
unsigned int width,
unsigned int height,
unsigned char bpp)
{
unsigned int i;
unsigned int j;
unsigned int row;
for (i=0; i < height*(bpp/8); i++) {
row = (i*width*(bpp/8));
for (j=0; j <= width*(bpp/8); j+=2) {
fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
| (fileSource[row+j]&0xE0);
fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
| ((fileSource[row+j]&0x1F)<<2);
}
}
}
+130
View File
@@ -0,0 +1,130 @@
/* ----------------------------------------------------------------------------
* 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
///
/// Utility for BMP
///
//------------------------------------------------------------------------------
#ifndef BMP_H
#define BMP_H
/// BMP magic number ('BM').
#define BMP_TYPE 0x4D42
/// headerSize must be set to 40
#define BITMAPINFOHEADER 40
//------------------------------------------------------------------------------
// Exported types
//------------------------------------------------------------------------------
#ifdef __ICCARM__ // IAR
#pragma pack(1) // IAR
#define __attribute__(...) // IAR
#endif // IAR
// BMP (Windows) Header Format
struct BMPHeader {
/// signature, must be 4D42 hex
unsigned short type;
/// size of BMP file in bytes (unreliable)
unsigned int fileSize;
/// reserved, must be zero
unsigned short reserved1;
/// reserved, must be zero
unsigned short reserved2;
/// offset to start of image data in bytes
unsigned int offset;
/// size of BITMAPINFOHEADER structure, must be 40
unsigned int headerSize;
/// image width in pixels
unsigned int width;
/// image height in pixels
unsigned int height;
/// number of planes in the image, must be 1
unsigned short planes;
/// number of bits per pixel (1, 4, 8, 16, 24, 32)
unsigned short bits;
/// compression type (0=none, 1=RLE-8, 2=RLE-4)
unsigned int compression;
/// size of image data in bytes (including padding)
unsigned int imageSize;
/// horizontal resolution in pixels per meter (unreliable)
unsigned int xresolution;
/// vertical resolution in pixels per meter (unreliable)
unsigned int yresolution;
/// number of colors in image, or zero
unsigned int ncolours;
/// number of important colors, or zero
unsigned int importantcolours;
} __attribute__ ((packed)); // GCC
#ifdef __ICCARM__ // IAR
#pragma pack() // IAR
#endif // IAR
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
extern unsigned char BMP_IsValid(void *file);
extern unsigned int BMP_GetFileSize(void *file);
extern unsigned char BMP_Decode(
void *file,
unsigned char *buffer,
unsigned int width,
unsigned int height,
unsigned char bpp);
extern void WriteBMPheader(unsigned int* pAddressHeader,
unsigned int bmpHSize,
unsigned int bmpVSize,
unsigned char bmpRgb,
unsigned char nbByte_Pixels);
extern void BMP_displayHeader(unsigned int* pAddressHeader);
extern void RGB565toBGR555(
unsigned char *fileSource,
unsigned char *fileDestination,
unsigned int width,
unsigned int height,
unsigned char bpp);
#endif //#ifndef BMP_H
@@ -0,0 +1,259 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "clock.h"
#include <board.h>
#include <utility/trace.h>
//------------------------------------------------------------------------------
// Internal types
//------------------------------------------------------------------------------
int currentConfig = 0; // 0 have to be the default configuration
//------------------------------------------------------------------------------
/// Describes a possible clock configuration (processor clock & master clock),
/// including the necessary register values.
//------------------------------------------------------------------------------
struct ClockConfiguration {
/// Processor clock frequency (in MHz).
unsigned short pck;
/// Master clock frequency (in MHz).
unsigned short mck;
/// CKGR_PLL reqister value.
unsigned int pllr;
/// PMC_MCKR register value.
unsigned int mckr;
};
//------------------------------------------------------------------------------
// Internal variables
//------------------------------------------------------------------------------
// Clock configurations for the AT91SAM9263-EK
#if defined(at91sam9263)
#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 200 MHz, MCK = 100 MHz
{200, 100, 0x206DBF09, 0x00000102},
// PCK = 240 MHz, MCK = 120 MHz
{240, 120, 0x202BC003, 0x00000102},
// PCK = 120 MHz, MCK = 120 MHz
{120, 120, 0x20156003, 0x00000002},
// PCK = 96 MHz, MCK = 48 MHz
{96, 48, 0x2057400F, 0x00000102},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x2057400F, 0x00000006}
};
// Clock configurations for the AT91SAM9G20-EK
#elif defined(at91sam9g20)
#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 400 MHz, MCK = 133 MHz
{400, 133, 0x202A0101, 0x00001302},
// PCK = 200 MHz, MCK = 100 MHz
{200, 100, 0x202A3F01, 0x0000010A},
// PCK = 96 MHz, MCK = 48 MHz
{96, 48, 0x207C3F03, 0x0000010E},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x207C3F03, 0x00000012}
};
// Clock configurations for the AT91SAM9XE-EK, AT91SAM9261-EK
#elif defined(at91sam9xe128) || \
defined(at91sam9xe256) || \
defined(at91sam9xe512) || \
defined(at91sam9261)
#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 200 MHz, MCK = 100 MHz
{200, 100, 0x208CBF0D, 0x00000102},
// PCK = 100 MHz, MCK = 100 MHz
{100, 100, 0x20273F07, 0x00000002},
// PCK = 96 MHz, MCK = 48 MHz
{96, 48, 0x20483F0E, 0x00000102},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x20483F0E, 0x00000006}
};
// Clock configurations for the AT91SAM9RL64-EK, AT91CAP9-DK, AT91CAP9-STK
#elif defined(at91sam9rl64) || \
defined(at91cap9)
#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 200 MHz, MCK = 100 MHz
{200, 100, 0x2031BF03, 0x00000102},
// PCK = 100 MHz, MCK = 100 MHz
{100, 100, 0x20183F03, 0x00000002},
// PCK = 96 MHz, MCK = 48 MHz
{96, 48, 0x20073F01, 0x00000102},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x20073F01, 0x00000006}
};
// Clock configuration for the AT91SAM7X-EK, AT91SAM7S-EK, AT91SAM7SE-EK
#elif defined(at91sam7x128) || defined(at91sam7x256) || defined(at91sam7x512) \
|| defined(at91sam7xc128) || defined(at91sam7xc256) || defined(at91sam7xc512) \
|| defined(at91sam7s16) || defined(at91sam7s161) || defined(at91sam7s32) \
|| defined(at91sam7s321) || defined(at91sam7s64) || defined(at91sam7s128) \
|| defined(at91sam7s256) || defined(at91sam7s512) || defined(at91sam7se32) \
|| defined(at91sam7se256) || defined(at91sam7se512)
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 55 MHz, MCK = 55 MHz
{55, 55, 0x006A3F12, 0x00000007},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x00483F0E, 0x00000007},
};
// Clock configuration for the AT91SAM7A3
#elif defined(at91sam7a3)
static const struct ClockConfiguration clockConfigurations[] = {
// PCK = 60 MHz, MCK = 60 MHz
{60, 60, 0x000C3F02, 0x00000007},
// PCK = 48 MHz, MCK = 48 MHz
{48, 48, 0x00483F0E, 0x00000007}
};
// No clock configuration
#else
#error No clock configuration for this board.
#endif
/// Number of available clock configurations
#define NB_CLOCK_CONFIGURATION (sizeof(clockConfigurations)/sizeof(clockConfigurations[0]))
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Sets the specified clock configuration.
/// \param configuration Index of the configuration to set.
//------------------------------------------------------------------------------
void CLOCK_SetConfig(unsigned char configuration)
{
printf("Setting clock configuration #%d ... ", configuration);
currentConfig = configuration;
// Switch to main oscillator in two operations
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
while ((PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
// Configure PLL
*AT91C_CKGR_PLLAR = clockConfigurations[configuration].pllr;
while ((PMC->PMC_SR & AT91C_PMC_LOCKA) == 0);
// Configure master clock in two operations
PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
while ((PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
while ((PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
// DBGU reconfiguration
DBGU_Configure(DBGU_STANDARD, 115200, clockConfigurations[configuration].mck*1000000);
printf("done.\n\r");
}
//------------------------------------------------------------------------------
/// Display the user menu on the DBGU.
//------------------------------------------------------------------------------
void CLOCK_DisplayMenu(void)
{
unsigned int i;
printf("\n\rMenu Clock configuration:\n\r");
for (i = 0; i < NB_CLOCK_CONFIGURATION; i++) {
printf(" %d: Set PCK = %3d MHz, MCK = %3d MHz %s\n\r",
i,
clockConfigurations[i].pck,
clockConfigurations[i].mck,
(currentConfig==i)?"(curr)":"");
}
}
//------------------------------------------------------------------------------
/// Get the current MCK
//------------------------------------------------------------------------------
unsigned short CLOCK_GetCurrMCK(void)
{
return clockConfigurations[currentConfig].mck;
}
//------------------------------------------------------------------------------
/// Get the current PCK
//------------------------------------------------------------------------------
unsigned short CLOCK_GetCurrPCK(void)
{
return clockConfigurations[currentConfig].pck;
}
//------------------------------------------------------------------------------
/// Change clock configuration.
//------------------------------------------------------------------------------
void CLOCK_UserChangeConfig(void)
{
unsigned char key = 0;
while (1)
{
CLOCK_DisplayMenu();
key = DBGU_GetChar();
if ((key >= '0') && (key <= ('0' + NB_CLOCK_CONFIGURATION - 1)))
{
CLOCK_SetConfig(key - '0');
break;
}
}
}
@@ -0,0 +1,47 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
#ifndef CLOCK_H
#define CLOCK_H
//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------
extern void CLOCK_SetConfig(unsigned char configuration);
extern void CLOCK_DisplayMenu(void);
extern void CLOCK_UserChangeConfig(void);
extern unsigned short CLOCK_GetCurrMCK(void);
extern unsigned short CLOCK_GetCurrPCK(void);
#endif //#ifndef FREQCONF_H
@@ -0,0 +1,316 @@
/* ----------------------------------------------------------------------------
* 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Function: Firmware encryption using hardware acceleration
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "aes_hardware.h"
#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
#include <stdio.h>
#include <string.h>
#include <board.h>
#include <utility/trace.h>
#include <utility/assert.h>
#include <pmc/pmc.h>
#include <aes/aes_p.h>
//------------------------------------------------------------------------------
// Inline functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Converts an ASCII value to an hexadecimal one
/// \param ASCII string
/// \param Buffer to store integer value
/// \param Length of string
//------------------------------------------------------------------------------
static inline void ASCII2Hex(const unsigned char * ascii,
unsigned char * binary,
unsigned int length)
{
unsigned int i;
for (i=0; i < length; i++) {
if (ascii[i*2] >= 'A') {
binary[i] = ascii[i*2] - 'A' + 10;
}
else {
binary[i] = ascii[i*2] - '0';
}
binary[i] <<= 4;
if (ascii[i*2+1] >= 'A') {
binary[i] += ascii[i*2+1] - 'A' + 10;
}
else {
binary[i] += ascii[i*2+1] - '0';
}
}
}
//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Initializes the AES peripheral
//------------------------------------------------------------------------------
#ifdef ONLY_ONE_ENCRYPTION
void aes_hard_init(void)
{
unsigned char key[16];
#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
unsigned char IV[16];
#endif
TRACE_DEBUG("AES/HARD: Initializing ...\n\r");
// Activate peripheral clock
#ifdef AT91C_ID_AES
PMC_EnablePeripheral( AT91C_ID_AES );
#elif AT91C_ID_AESTDES
PMC_EnablePeripheral( AT91C_ID_AESTDES );
#elif AT91C_ID_TDES
PMC_EnablePeripheral( AT91C_ID_TDES );
#else
#error AES undefined
#endif
// Load mode
#if defined(ENCRYPTION_ECB)
//AES_Configure(AT91C_AES_CIPHER, AT91C_AES_SMOD_PDC, AT91C_AES_OPMOD_ECB);
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_ECB;
#elif defined(ENCRYPTION_CBC)
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_CBC;
#elif defined(ENCRYPTION_CTR)
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_CTR;
#endif
// Convert and load key
ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
AES_SetKey((unsigned int*)key);
// Convert and load IV
#if defined(ENCRYPTION_CTR) || defined(ENCRYPTION_CBC)
ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
AES_SetVector((unsigned int*)IV);
#endif
TRACE_DEBUG("AES/HARD: Initialization done.\n\r");
}
#endif
//------------------------------------------------------------------------------
/// Initializes the AES peripheral for CBC mode
//------------------------------------------------------------------------------
#ifndef ONLY_ONE_ENCRYPTION
#if defined(ENCRYPTION_CBC)
void aes_hard_init_CBC(void)
{
unsigned char key[16];
unsigned char IV[16];
TRACE_DEBUG("aes_hard_init_CBC\n\r");
// Activate peripheral clock
#ifdef AT91C_ID_AES
PMC_EnablePeripheral( AT91C_ID_AES );
#elif AT91C_ID_AESTDES
PMC_EnablePeripheral( AT91C_ID_AESTDES );
#elif AT91C_ID_TDES
PMC_EnablePeripheral( AT91C_ID_TDES );
#else
#error AES undefined
#endif
// Load mode
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_CBC;
// Convert and load key
ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
AES_SetKey((unsigned int*)key);
// Convert and load IV
ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
AES_SetVector((unsigned int*)IV);
}
#endif
//------------------------------------------------------------------------------
/// Initializes the AES peripheral for CTR mode
//------------------------------------------------------------------------------
#if defined(ENCRYPTION_CTR)
void aes_hard_init_CTR(void)
{
unsigned char key[16];
unsigned char IV[16];
TRACE_DEBUG("aes_hard_init_CTR\n\r");
// Activate peripheral clock
#ifdef AT91C_ID_AES
PMC_EnablePeripheral( AT91C_ID_AES );
#elif AT91C_ID_AESTDES
PMC_EnablePeripheral( AT91C_ID_AESTDES );
#elif AT91C_ID_TDES
PMC_EnablePeripheral( AT91C_ID_TDES );
#else
#error AES undefined
#endif
// Load mode
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_CTR;
// Convert and load key
ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
AES_SetKey((unsigned int*)key);
// Convert and load IV
ASCII2Hex((unsigned char*)ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
AES_SetVector((unsigned int*)IV);
}
#endif
//------------------------------------------------------------------------------
/// Initializes the AES peripheral for ECB mode
//------------------------------------------------------------------------------
#if defined(ENCRYPTION_ECB)
void aes_hard_init_ECB(void)
{
unsigned char key[16];
TRACE_DEBUG("aes_hard_init_ECB\n\r");
// Activate peripheral clock
#ifdef AT91C_ID_AES
PMC_EnablePeripheral( AT91C_ID_AES );
#elif AT91C_ID_AESTDES
PMC_EnablePeripheral( AT91C_ID_AESTDES );
#elif AT91C_ID_TDES
PMC_EnablePeripheral( AT91C_ID_TDES );
#else
#error AES undefined
#endif
// Load mode
//AES_Configure(AT91C_AES_CIPHER, AT91C_AES_SMOD_MANUAL, AT91C_AES_OPMOD_ECB);
AT91C_BASE_AES->AES_MR = AT91C_AES_SMOD_PDC | AT91C_AES_OPMOD_ECB;
// Convert and load key
ASCII2Hex((unsigned char*)ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
AES_SetKey((unsigned int*)key);
}
#endif
#endif // ONLY_ONE_ENCRYPTION
//------------------------------------------------------------------------------
/// Cleans up the AES peripheral
//------------------------------------------------------------------------------
void aes_hard_cleanup(void)
{
TRACE_DEBUG("AES/HARD: Cleaning up ...\n\r");
AT91C_BASE_AES->AES_MR = 0;
#ifdef AT91C_ID_AES
PMC_DisablePeripheral( AT91C_ID_AES );
#elif AT91C_ID_AESTDES
PMC_DisablePeripheral( AT91C_ID_AESTDES );
#elif AT91C_ID_TDES
PMC_DisablePeripheral( AT91C_ID_TDES );
#else
#error AES undefined
#endif
// Close PDC
AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_RXTDIS;
AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_TXTDIS;
// Reset all Counter register Next buffer first
AT91C_BASE_PDC_AES->PDC_TNPR = 0;
AT91C_BASE_PDC_AES->PDC_TNCR = 0;
AT91C_BASE_PDC_AES->PDC_RPR = 0;
AT91C_BASE_PDC_AES->PDC_RCR = 0;
AT91C_BASE_PDC_AES->PDC_TPR = 0;
AT91C_BASE_PDC_AES->PDC_TCR = 0;
AT91C_BASE_PDC_AES->PDC_RPR = 0;
AT91C_BASE_PDC_AES->PDC_RCR = 0;
TRACE_DEBUG("AES/HARD: Cleanup done.\n\r");
}
//------------------------------------------------------------------------------
/// Decrypts a variable-length cipher text
/// \param pCipherText text to decrypt
/// \param pPlainText to store plain text
/// \param length of cipher text (in bytes)
/// \return: 1 if ok, 0 if error
//------------------------------------------------------------------------------
int aes_hard_decrypt(const unsigned char *pCipherText,
unsigned char *pPlainText,
unsigned int length)
{
TRACE_DEBUG("aes_hard_decrypt\n\r");
// Check parameters
if ((pCipherText == NULL) || (pPlainText == NULL)) {
return 0;
}
// Set source and destination buffers in PDC
AT91C_BASE_PDC_AES->PDC_TPR = (unsigned int) pCipherText;
AT91C_BASE_PDC_AES->PDC_RPR = (unsigned int) pPlainText;
AT91C_BASE_PDC_AES->PDC_TCR = length >> 2;
AT91C_BASE_PDC_AES->PDC_RCR = length >> 2;
// Start decryption and wait
AT91C_BASE_PDC_AES->PDC_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
while (((AES_GetStatus()) & AT91C_AES_ENDRX) == 0);
return 1;
}
#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
@@ -0,0 +1,100 @@
/* ----------------------------------------------------------------------------
* 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
///
/// Firmware encryption using AES hardware acceleration
/// This code is based on the AES reference implementation published by Paulo
/// Barreto and Vincent Rijmen.
///
/// !Usage
///
/// -# aes_hard_init: Initialize AES hardware
/// -# aes_hard_init_CBC: for the CBC mode
/// -# aes_hard_init_CTR: for the CTR mode
/// -# aes_hard_init_ECB: for the ECB mode
/// -# aes_hard_cleanup: Cleans up AES
/// -# aes_hard_decrypt: Decrypts a variable-length cipher text
//------------------------------------------------------------------------------
#ifndef BOOTLOADER_AES_HARDWARE_H
#define BOOTLOADER_AES_HARDWARE_H
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "config.h"
#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
//------------------------------------------------------------------------------
// Check configuration
//------------------------------------------------------------------------------
#if (ENCRYPTION_KEY_LENGTH != 16)
#error Hardware AES acceleration only supports 128 bits keys.
#endif
#if (ENCRYPTION_BLOCK_LENGTH != 16)
#error Hardware AES acceleration only supports 128 bits blocks.
#endif
#if !defined(ENCRYPTION_ECB) && \
!defined(ENCRYPTION_CBC) && \
!defined(ENCRYPTION_CTR)
#error Only ECB, CBC & CTR modes are supported.
#endif
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
#ifdef ONLY_ONE_ENCRYPTION
#define ENCRYPTION_INIT aes_hard_init
#define ENCRYPTION_CLEANUP aes_hard_cleanup
#define ENCRYPTION_DECRYPT aes_hard_decrypt
#endif
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
extern void aes_hard_init(void);
#ifndef ONLY_ONE_ENCRYPTION
extern void aes_hard_init_CBC(void);
extern void aes_hard_init_CTR(void);
extern void aes_hard_init_ECB(void);
#endif
extern void aes_hard_cleanup(void);
extern int aes_hard_decrypt(const unsigned char *, unsigned char *, unsigned int);
#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_HARD)
#endif // BOOTLOADER_AES_HARDWARE_H

Some files were not shown because too many files have changed in this diff Show More