diff --git a/DSTAT-temp/src/asf/common/drivers/nvm/common_nvm.h b/DSTAT-temp/src/asf/common/drivers/nvm/common_nvm.h new file mode 100644 index 0000000000000000000000000000000000000000..1ddd46cce4734b4b08984cc145c0a6294234073e --- /dev/null +++ b/DSTAT-temp/src/asf/common/drivers/nvm/common_nvm.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief Non volatile memories management + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef COMMON_NVM_H_INCLUDED +#define COMMON_NVM_H_INCLUDED + +#include "compiler.h" +#include "conf_board.h" +#include "parts.h" +#include "status_codes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) +#include "at45dbx.h" +#endif + +/* ! \name Non volatile memory types */ +/* ! @{ */ +typedef enum { + INT_FLASH /* !< Internal Flash */ + +#if (XMEGA || UC3 || SAM4S) + , INT_USERPAGE /* !< Userpage/User signature */ +#endif + +#if XMEGA + , INT_EEPROM /* !< Internal EEPROM */ +#endif + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + , AT45DBX /* !< External AT45DBX dataflash */ +#endif +} mem_type_t; +/* ! @} */ + +#if SAM +# ifndef IFLASH_PAGE_SIZE +# define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE +# endif + +# ifndef IFLASH_ADDR +# define IFLASH_ADDR IFLASH0_ADDR +# endif +#endif + +/** + * \defgroup nvm_group NVM service + * + * See \ref common_nvm_quickstart. + * + * This is the common API for non volatile memories. Additional features are + * available + * in the documentation of the specific modules. + * + */ + +/** + * \brief Initialize the non volatile memory specified. + * + * \param mem Type of non volatile memory to initialize + */ +status_code_t nvm_init(mem_type_t mem); + +/** + * \brief Read single byte of data. + * + * \param mem Type of non volatile memory to read + * \param address Address to read + * \param data Pointer to where to store the read data + */ +status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data); + +/** + * \brief Write single byte of data. + * + * \param mem Type of non volatile memory to write + * \param address Address to write + * \param data Data to be written + */ +status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data); + +/** + * \brief Read \a len number of bytes from address \a address in non volatile + * memory \a mem and store it in the buffer \a buffer + * + * \param mem Type of non volatile memory to read + * \param address Address to read + * \param buffer Pointer to destination buffer + * \param len Number of bytes to read + */ +status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer, + uint32_t len); + +/** + * \brief Write \a len number of bytes at address \a address in non volatile + * memory \a mem from the buffer \a buffer + * + * \param mem Type of non volatile memory to write + * \param address Address to write + * \param buffer Pointer to source buffer + * \param len Number of bytes to write + */ +status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer, + uint32_t len); + +/** + * \brief Erase a page in the non volatile memory. + * + * \param mem Type of non volatile memory to erase + * \param page_number Page number to erase + */ +status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number); + +/** + * \brief Get the size of whole non volatile memory specified. + * + * \param mem Type of non volatile memory + * \param size Pointer to where to store the size + */ +status_code_t nvm_get_size(mem_type_t mem, uint32_t *size); + +/** + * \brief Get the size of a page in the non volatile memory specified. + * + * \param mem Type of non volatile memory + * \param size Pointer to where to store the size + */ +status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size); + +/** + * \brief Get the page number from the byte address \a address. + * + * \param mem Type of non volatile memory + * \param address Byte address of the non volatile memory + * \param num Pointer to where to store the page number + */ +status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address, + uint32_t *num); + +/** + * \brief Enable security bit which blocks external read and write access + * to the device. + * + */ +status_code_t nvm_set_security_bit(void); + +/** + * \page common_nvm_quickstart Quick Start quide for common NVM driver + * + * This is the quick start quide for the \ref nvm_group "Common NVM driver", + * with step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section nvm_basic_use_case Basic use case + * In this basic use case, NVM driver is configured for Internal Flash + * + * \section nvm_basic_use_case_setup Setup steps + * + * \subsection nvm_basic_use_case_setup_code Example code + * Add to you application C-file: + * \code + * if(nvm_init(INT_FLASH) == STATUS_OK) + * do_something(); + * \endcode + * + * \subsection nvm_basic_use_case_setup_flow Workflow + * -# Ensure that board_init() has configured selected I/Os for TWI function + * when using external AT45DBX dataflash + * -# Ensure that \ref conf_nvm.h is present for the driver. + * - \note This file is only for the driver and should not be included by the + * user. + * -# Call nvm_init \code nvm_init(INT_FLASH); \endcode + * and optionally check its return code + * + * \section nvm_basic_use_case_usage Usage steps + * \subsection nvm_basic_use_case_usage_code_writing Example code: Writing to + * non volatile memory + * Use in the application C-file: + * \code + * uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; + * + * if(nvm_write(INT_FLASH, test_address, (void *)buffer, sizeof(buffer)) == + * STATUS_OK) + * do_something(); + * \endcode + * + * \subsection nvm_basic_use_case_usage_flow Workflow + * -# Prepare the data you want to send to the non volatile memory + * \code uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; \endcode + * -# Call nvm_write \code nvm_write(INT_FLASH, test_address, (void *)buffer, + * sizeof(buffer)) \endcode + * and optionally check its return value for STATUS_OK. + * + * \subsection nvm_basic_use_case_usage_code_reading Example code: Reading from + * non volatile memory + * Use in application C-file: + * \code + * uint8_t data_read[8]; + * + * if(nvm_read(INT_FLASH, test_address, (void *)data_read, sizeof(data_read)) + * == STATUS_OK) { + * //Check read content + * if(data_read[0] == 0xAA) + * do_something(); + * } + * \endcode + * + * \subsection nvm_basic_use_case_usage_flow Workflow + * -# Prepare a data buffer that will read data from non volatile memory + * \code uint8_t data_read[8]; \endcode + * -# Call nvm_read \code nvm_read(INT_FLASH, test_address, (void *)data_read, + * sizeof(data_read)); \endcode + * and optionally check its return value for STATUS_OK. + * The data read from the non volatile memory are in data_read. + * + * \subsection nvm_basic_use_case_usage_code_erasing Example code: Erasing a + * page of non volatile memory + * Use in the application C-file: + * \code + * if(nvm_page_erase(INT_FLASH, test_page) == STATUS_OK) + * do_something(); + * \endcode + * + * \subsection nvm_basic_use_case_usage_flow Workflow + * -# Call nvm_page_erase \code nvm_page_erase(INT_FLASH, test_page) \endcode + * and optionally check its return value for STATUS_OK. + * + * \subsection nvm_basic_use_case_usage_code_config Example code: Reading + *configuration of non volatile memory + * Use in application C-file: + * \code + * uint8_t mem_size, page_size, page_num; + * + * nvm_get_size(INT_FLASH, &mem_size); + * nvm_get_page_size(INT_FLASH, &page_size); + * nvm_get_pagenumber(INT_FLASH, test_address, &page_num); + * \endcode + * + * \subsection nvm_basic_use_case_usage_flow Workflow + * -# Prepare a buffer to store configuration of non volatile memory + * \code uint8_t mem_size, page_size, page_num; \endcode + * -# Call nvm_get_size \code nvm_get_size(INT_FLASH, &mem_size); \endcode + * and optionally check its return value for STATUS_OK. + * The memory size of the non volatile memory is in mem_size. + * -# Call nvm_get_page_size \code nvm_get_page_size(INT_FLASH, &page_size); + * \endcode + * and optionally check its return value for STATUS_OK. + * The page size of the non volatile memory is in page_size. + * -# Call nvm_get_pagenumber \code nvm_get_page_number(INT_FLASH, test_address, + * &page_num); \endcode + * and optionally check its return value for STATUS_OK. + * The page number of given address in the non volatile memory is in page_num. + * + * \subsection nvm_basic_use_case_usage_code_locking Example code: Enabling + * security bit + * Use in the application C-file: + * \code + * if(nvm_set_security_bit() == STATUS_OK) + * do_something(); + * \endcode + * + * \subsection nvm_basic_use_case_usage_flow Workflow + * -# Call nvm_set_security_bit \code nvm_set_security_bit() \endcode + * and optionally check its return value for STATUS_OK. + */ + +#ifdef __cplusplus +} +#endif + +#endif /* COMMON_NVM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/common/drivers/nvm/xmega/xmega_nvm.c b/DSTAT-temp/src/asf/common/drivers/nvm/xmega/xmega_nvm.c new file mode 100644 index 0000000000000000000000000000000000000000..385a41f99b0e9b92503ac3187f820dfc1c3432d6 --- /dev/null +++ b/DSTAT-temp/src/asf/common/drivers/nvm/xmega/xmega_nvm.c @@ -0,0 +1,331 @@ +/** + * \file + * + * \brief Non volatile memories management for XMEGA devices + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "common_nvm.h" +#include "conf_nvm.h" +#include "nvm.h" + +status_code_t nvm_init(mem_type_t mem) +{ + switch (mem) { + case INT_FLASH: + case INT_USERPAGE: + case INT_EEPROM: + /* No initialization required for internal memory */ + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + /* Initialize dataflash */ + at45dbx_init(); + /* Perform memory check */ + if (!at45dbx_mem_check()) { + return ERR_NO_MEMORY; + } + break; +#endif + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data) +{ + switch (mem) { + case INT_FLASH: + *data = nvm_flash_read_byte((flash_addr_t)address); + break; + + case INT_USERPAGE: + nvm_user_sig_read_buffer((flash_addr_t)address, (void *)data, + 1); + break; + + case INT_EEPROM: + *data = nvm_eeprom_read_byte((eeprom_addr_t)address); + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + if (!at45dbx_read_byte_open(address)) { + return ERR_BAD_ADDRESS; + } + + *data = at45dbx_read_byte(); + at45dbx_read_close(); + break; +#endif + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data) +{ + switch (mem) { + case INT_FLASH: + nvm_flash_erase_and_write_buffer((flash_addr_t)address, + (const void *)&data, 1, true); + break; + + case INT_USERPAGE: + nvm_user_sig_write_buffer((flash_addr_t)address, + (const void *)&data, 1, true); + break; + + case INT_EEPROM: + nvm_eeprom_write_byte((eeprom_addr_t)address, data); + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + if (!at45dbx_write_byte_open(address)) { + return ERR_BAD_ADDRESS; + } + + at45dbx_write_byte(data); + at45dbx_write_close(); +#endif + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer, + uint32_t len) +{ + switch (mem) { + case INT_FLASH: + nvm_flash_read_buffer((flash_addr_t)address, buffer, + (uint16_t)len); + break; + + case INT_USERPAGE: + nvm_user_sig_read_buffer((flash_addr_t)address, buffer, + (uint16_t)len); + break; + + case INT_EEPROM: + nvm_eeprom_read_buffer((eeprom_addr_t)address, buffer, + (uint16_t)len); + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + { + uint32_t sector = address / AT45DBX_SECTOR_SIZE; + if (!at45dbx_read_sector_open(sector)) { + return ERR_BAD_ADDRESS; + } + + at45dbx_read_sector_to_ram(buffer); + at45dbx_read_close(); + } + break; +#endif + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer, + uint32_t len) +{ + switch (mem) { + case INT_FLASH: + nvm_flash_erase_and_write_buffer((flash_addr_t)address, + (const void *)buffer, len, true); + break; + + case INT_USERPAGE: + nvm_user_sig_write_buffer((flash_addr_t)address, + (const void *)buffer, len, true); + break; + + case INT_EEPROM: + nvm_eeprom_erase_and_write_buffer((eeprom_addr_t)address, + (const void *)buffer, len); + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + { + uint32_t sector = address / AT45DBX_SECTOR_SIZE; + if (!at45dbx_write_sector_open(sector)) { + return ERR_BAD_ADDRESS; + } + + at45dbx_write_sector_from_ram((const void *)buffer); + at45dbx_write_close(); + } + break; +#endif + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number) +{ + switch (mem) { + case INT_FLASH: + if ((page_number >= 0) && + (page_number < + (BOOT_SECTION_START / FLASH_PAGE_SIZE))) { + nvm_flash_erase_app_page((flash_addr_t)(page_number * + FLASH_PAGE_SIZE)); + } else if ((page_number >= 0) && + (page_number < + (BOOT_SECTION_END / FLASH_PAGE_SIZE))) { + nvm_flash_erase_boot_page((flash_addr_t)(page_number * + FLASH_PAGE_SIZE)); + } else { + return ERR_INVALID_ARG; + } + + break; + + case INT_USERPAGE: + nvm_flash_erase_user_section(); + break; + + case INT_EEPROM: + nvm_eeprom_erase_page((uint8_t)page_number); + break; + + default: + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_get_size(mem_type_t mem, uint32_t *size) +{ + switch (mem) { + case INT_FLASH: + *size = (uint32_t)FLASH_SIZE; + break; + + case INT_USERPAGE: + *size = (uint32_t)FLASH_PAGE_SIZE; + break; + + case INT_EEPROM: + *size = (uint32_t)EEPROM_SIZE; + break; + +#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) + case AT45DBX: + *size = (uint32_t)AT45DBX_MEM_SIZE; + break; +#endif + + default: + /* Other memories not supported */ + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size) +{ + switch (mem) { + case INT_FLASH: + case INT_USERPAGE: + *size = (uint32_t)FLASH_PAGE_SIZE; + break; + + case INT_EEPROM: + *size = (uint32_t)EEPROM_PAGE_SIZE; + break; + + default: + /* Other memories not supported */ + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address, + uint32_t *num) +{ + switch (mem) { + case INT_FLASH: + *num = (uint32_t)(address / FLASH_PAGE_SIZE); + break; + + case INT_EEPROM: + *num = (uint32_t)(address / EEPROM_PAGE_SIZE); + break; + + default: + /* Other memories not supported */ + return ERR_INVALID_ARG; + } + + return STATUS_OK; +} + +status_code_t nvm_set_security_bit(void) +{ + /* Block external programming access to the device */ + nvm_lb_lock_bits_write(NVM_LB_RWLOCK_gc); + return STATUS_OK; +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 0000000000000000000000000000000000000000..ed48499b1b7cede8465120fbef2505091b45877b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c new file mode 100644 index 0000000000000000000000000000000000000000..44bb9c1dc2a29cd8a792626fd1c978a23ce38c5d --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/avr8_hugemem.c @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "hugemem.h" +#include "compiler.h" +#include "conf_board.h" + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if defined(__GNUC__) || defined(__DOXYGEN__) +uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + uint16_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + uint32_t value; + + asm( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %A0, Z+ \n\t" + "ld %B0, Z+ \n\t" + "ld %C0, Z+ \n\t" + "ld %D0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "get_%=: \n\t" + "ld __tmp_reg__, Z+ \n\t" + "st X+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne get_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(to), "+w"(size) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z, %B1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + asm( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z+, %A1 \n\t" + "st Z+, %B1 \n\t" + "st Z+, %C1 \n\t" + "st Z, %D1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + if (size > 0) { + asm volatile( + "movw r30, %A2 \n\t" + "out %3, %C2 \n\t" + "put_%=: \n\t" + "ld __tmp_reg__, X+ \n\t" + "st Z+, __tmp_reg__ \n\t" + "sbiw %A1, 1 \n\t" + "brne put_%= \n\t" + "out %3, __zero_reg__ \n\t" + : "+x"(from), "+w"(size) + : "r"(to), "i"(&RAMPZ) + : "r30", "r31" + ); + } +} +# endif /* __GNUC__ */ + +# ifdef __ICCAVR__ +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) +{ + uint8_t *to_ptr; + uint8_t __huge *from_ptr; + + // Ensure that the address range to copy to is within 64 kB boundary. + Assert(((uint32_t)to + size) <= 0x10000); + + to_ptr = (uint8_t *)to; + from_ptr = (uint8_t __huge *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} + +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) +{ + uint8_t __huge *to_ptr; + uint8_t *from_ptr; + + // Ensure that the address range to copy from is within 64 kB boundary. + Assert(((uint32_t)from + size) <= 0x10000); + + to_ptr = (uint8_t __huge *)to; + from_ptr = (uint8_t *)from; + + for (; size > 0; size--) { + *to_ptr++ = *from_ptr++; + } +} +# endif /* __ICCAVR__ */ +#endif /* CONFIG_HAVE_HUGEMEM */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..76a612b8fc122a1ea911280a5642a5937c40fb39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/avr8/hugemem.h @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief Access to huge data memory with 8-bit AVR + * + * Do not include this file directly, but rather . + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef AVR8_HUGEMEM_H_INCLUDED +#define AVR8_HUGEMEM_H_INCLUDED + +#include +#include "conf_board.h" + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_avr8_group Hugemem implementation for 8-bit AVR. + * + * GCC does not have native support for 24-bit pointers, and therefore requires + * custom assembly functions for this purpose. The implemented functions leave + * RAMPZ cleared upon exit.\par + * + * If the chip does not support huge memory, i.e., \a CONFIG_HAVE_HUGEMEM is + * not defined, a generic implementation will be used. + */ + +#if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__) +# if XMEGA && !(XMEGA_A1 || XMEGA_A1U) +# error CONFIG_HAVE_HUGEMEM is not supported on XMEGA parts without EBI. +# endif +# if defined(__GNUC__) || defined(__DOXYGEN__) +#include + +#include "compiler.h" + +typedef uint32_t hugemem_ptr_t; + +#define HUGEMEM_NULL 0 + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + uint8_t value; + + asm volatile( + "movw r30, %A1 \n\t" + "out %2, %C1 \n\t" + "ld %0, Z \n\t" + "out %2, __zero_reg__ \n\t" + : "=r"(value) + : "r"(from), "i"(&RAMPZ) + : "r30", "r31" + ); + + return value; +} + +uint_fast16_t hugemem_read16(const hugemem_ptr_t from); +uint_fast32_t hugemem_read32(const hugemem_ptr_t from); + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + asm volatile( + "movw r30, %A0 \n\t" + "out %2, %C0 \n\t" + "st Z, %1 \n\t" + "out %2, __zero_reg__ \n\t" + : + : "r"(to), "r"(val), "i"(&RAMPZ) + : "r30", "r31" + ); +} + +void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val); +void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val); + +# elif defined(__ICCAVR__) +#include + +typedef void __huge *hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint_fast8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(volatile __huge uint8_t *)from; +} + +static inline uint_fast16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(volatile __huge uint16_t *)from; +} + +static inline uint_fast32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(volatile __huge uint32_t *)from; +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) +{ + *(__huge uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) +{ + *(__huge uint16_t *)to = val; +} + +static inline void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) +{ + *(__huge uint32_t *)to = val; +} +# endif /* __ICCAVR__ */ + +void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size); +void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size); + +#else +# include +#endif /* CONFIG_HAVE_HUGEMEM */ +//@} + +#endif /* AVR8_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..5f43e01008999a4e8a47bbfbacdd39f8b93b6c4e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/generic/hugemem.h @@ -0,0 +1,112 @@ +/** + * \file + * + * \brief Generic implementation of huge data memory access + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef GENERIC_HUGEMEM_H_INCLUDED +#define GENERIC_HUGEMEM_H_INCLUDED + +#include +#include + +/** + * \weakgroup hugemem_group + * @{ + */ + +/** + * \internal + * \defgroup hugemem_generic_group Generic hugemem implementation. + * + * These functions are needed for code compatibility between 8- and 32-bit AVR, + * as well as a different application configurations on 8-bit AVR, i.e., if huge + * data memory is optional. + */ + +typedef void * hugemem_ptr_t; + +#define HUGEMEM_NULL NULL + +static inline uint8_t hugemem_read8(const hugemem_ptr_t from) +{ + return *(uint8_t *)from; +} + +static inline uint16_t hugemem_read16(const hugemem_ptr_t from) +{ + return *(uint16_t *)from; +} + +static inline uint32_t hugemem_read32(const hugemem_ptr_t from) +{ + return *(uint32_t *)from; +} + +static inline void hugemem_read_block(void *to, const hugemem_ptr_t from, + size_t size) +{ + memcpy(to, from, size); +} + +static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val) +{ + *(uint8_t *)to = val; +} + +static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val) +{ + *(uint16_t *)to = val; +} + + +static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val) +{ + *(uint32_t *)to = val; +} + +static inline void hugemem_write_block(hugemem_ptr_t to, const void *from, + size_t size) +{ + memcpy(to, from, size); +} + +//@} + +#endif /* GENERIC_HUGEMEM_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h new file mode 100644 index 0000000000000000000000000000000000000000..fca49470fa37fddd85036485eb706ed399079ee8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/hugemem/hugemem.h @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief Huge data memory space access + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef HUGEMEM_H_INCLUDED +#define HUGEMEM_H_INCLUDED + +#include +#include + +#if defined(__AVR32__) || defined(__ICCAVR32__) +# include +#elif defined(__AVR__) || defined (__ICCAVR__) +# include +#else +# error Unknown architecture passed to hugemem interface. +# error Expected __AVR32__ or __AVR__. +#endif + +/** + * \defgroup hugemem_group Data in Huge Data Memory Space + * + * Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are + * needed for access to data beyond the 64 kB boundary, i.e., addresses that + * are larger than 16-bit. + * + * The definition of huge memory space can differ between architectures, so the + * implementation is architecture specific. + * + * This module supplies functions for copying a number of bytes between huge + * and 64 kB data memory space, and is needed solely for code compatibility + * across compilers. + * + * @{ + */ + +/** + * \typedef hugemem_ptr_t + * + * \brief Type to use for pointers to huge memory. + */ + +/** + * \def HUGEMEM_NULL + * + * \brief Hugemem null pointer, similar to NULL, but works across different + * platforms. + */ + +/** + * \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from) + * + * \brief Read 8-bit value stored at huge memory address \a from. + */ + +/** + * \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from) + * + * \brief Read 16-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size) + * + * \brief Read \a size bytes from huge memory address \a from into buffer at + * address \a to. + */ + +/** + * \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from) + * + * \brief Read 32-bit value stored at huge memory address \a from. + */ + +/** + * \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val) + * + * \brief Write 8-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val) + * + * \brief Write 16-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val) + * + * \brief Write 32-bit value \a val to huge memory address \a to. + */ + +/** + * \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size) + * + * \brief Write \a size bytes from buffer at address \a from to huge memory + * address \a to. + */ + +//@} + +#endif /* HUGEMEM_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..a27fb7b3c2fd229373d4e745e4d2eb2c21a0e741 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/ioport.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * + * ioport_init(); + * + * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + * \endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * bool value; + * + * value = ioport_get_pin_level(MY_BUTTON); + * ioport_set_pin_level(MY_LED, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * #define MASK 0x00000060 + * + * ioport_init(); + * + * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); + * \endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + * #define IN_PORT IOPORT_PORTA + * #define OUT_PORT IOPORT_PORTB + * \endcode + * - \note The port names differ between architectures: + * - XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + * ioport_port_mask_t value; + * + * value = ioport_get_port_level(IN_PORT, MASK); + * ioport_set_port_level(OUT_PORT, MASK, value); + * \endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h new file mode 100644 index 0000000000000000000000000000000000000000..5b2f21f49a22f96467dabf9839fc570e5ba9b30f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport.h @@ -0,0 +1,337 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index(ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ + +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + PORTCFG.MPCMASK = mask; + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + PORTCFG.MPCMASK = arch_ioport_pin_to_mask(pin); + base->PIN0CTRL = mode; +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTSET = mask & level; + base->OUTCLR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl = + (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 0000000000000000000000000000000000000000..af81a81cd3478b5f6df80be6839c82031c041066 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed6ec5eef1098b4bd9086f2b5bfbbeddee967f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..92a29c7bee896f21b09028c77431daa9e3587760 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode++; + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..658666ab8329055c356292b464f003cb2f5989fe --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 0000000000000000000000000000000000000000..e50fab9545b0669ced1c359091b50da365a4693f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..af9a20d78e77dec184a9c039e9a07dcf4ce57390 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/usart_spi.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..b099f2c9633a1141b334d92b78e8c059f0a21cd3 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..0824830c3d55e886fb3f25b70e5483e08f0da2bf --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,239 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_putchar(usart,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_getchar(usart); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..9f71bfecd6da22eda12a39e03eb80f603d6b73f2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.c @@ -0,0 +1,1037 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc.h" +#include "udi_cdc.h" +#include + +#ifdef UDI_CDC_LOW_RATE +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#else +# ifdef USB_DEVICE_HS_SUPPORT +# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) +# else +# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) +# endif +#endif + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_cdc_comm_enable(void); +void udi_cdc_comm_disable(void); +bool udi_cdc_comm_setup(void); +bool udi_cdc_data_enable(void); +void udi_cdc_data_disable(void); +bool udi_cdc_data_setup(void); +uint8_t udi_cdc_getsetting(void); +void udi_cdc_data_sof_notify(void); +UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { + .enable = udi_cdc_comm_enable, + .disable = udi_cdc_comm_disable, + .setup = udi_cdc_comm_setup, + .getsetting = udi_cdc_getsetting, +}; +UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { + .enable = udi_cdc_data_enable, + .disable = udi_cdc_data_disable, + .setup = udi_cdc_data_setup, + .getsetting = udi_cdc_getsetting, + .sof_notify = udi_cdc_data_sof_notify, +}; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_internal Implementation of UDI CDC + * + * Class internal implementation + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \name Routines to control serial line + */ +//@{ + +/** + * \brief Returns the port number corresponding at current setup request + * + * \return port number + */ +static uint8_t udi_cdc_setup_to_port(void); + +/** + * \brief Sends line coding to application + * + * Called after SETUP request when line coding data is received. + */ +static void udi_cdc_line_coding_received(void); + +/** + * \brief Records new state + * + * \param port Communication port number to manage + * \param b_set State is enabled if true, else disabled + * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) + */ +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); + +/** + * \brief Check and eventually notify the USB host of new state + * + * \param port Communication port number to manage + * \param ep Port communication endpoint + */ +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); + +/** + * \brief Ack sent of serial state message + * Callback called after serial state message sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +//@} + +/** + * \name Routines to process data transfer + */ +//@{ + +/** + * \brief Enable the reception of data from the USB host + * + * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. + * + * \param port Communication port number to manage + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +static bool udi_cdc_rx_start(uint8_t port); + +/** + * \brief Update rx buffer management with a new data + * Callback called after data reception on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finish + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data received + */ +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Ack sent of tx buffer + * Callback called after data transfer on USB line + * + * \param status UDD_EP_TRANSFER_OK, if transfer finished + * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted + * \param n number of data transfered + */ +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); + +/** + * \brief Send buffer on line or wait a SOF event + * + * \param port Communication port number to manage + */ +static void udi_cdc_tx_send(uint8_t port); + +//@} + +//@} + +/** + * \name Information about configuration of communication line + */ +//@{ +static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; +static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; +static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; +COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; + +//! Status of CDC COMM interfaces +static volatile uint8_t udi_cdc_nb_comm_enabled = 0; +//@} + +/** + * \name Variables to manage RX/TX transfer requests + * Two buffers for each sense are used to optimize the speed. + */ +//@{ + +//! Status of CDC DATA interfaces +static volatile uint8_t udi_cdc_nb_data_enabled = 0; +static volatile bool udi_cdc_data_running = false; +//! Buffer to receive data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; +//! Data available in RX buffers +static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give the current RX buffer used (rx0 if 0, rx1 if 1) +static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; +//! Read position in current RX buffer +static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; + +//! Define a transfer halted +#define UDI_CDC_TRANS_HALTED 2 + +//! Buffer to send data +COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; +//! Data available in TX buffers +static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; +//! Give current TX buffer used (tx0 if 0, tx1 if 1) +static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; +//! Value of SOF during last TX transfer +static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; +//! Signal a transfer on-going +static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; +//! Signal that both buffer content data to send +static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; + +//@} + +bool udi_cdc_comm_enable(void) +{ + uint8_t port; + uint8_t iface_comm_num; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_comm_enabled = 0; +#else + if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_comm_enabled = 0; + } + port = udi_cdc_nb_comm_enabled; +#endif + + // Initialize control signal management + udi_cdc_state[port] = CPU_TO_LE16(0); + + uid_cdc_state_msg[port].header.bmRequestType = + USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | + USB_REQ_RECIP_INTERFACE; + uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; + uid_cdc_state_msg[port].header.wValue = LE16(0); + + switch (port) { +#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ + case index: \ + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) +#undef UDI_CDC_PORT_TO_IFACE_COMM + default: + iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; + break; + } + + uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); + uid_cdc_state_msg[port].header.wLength = LE16(2); + uid_cdc_state_msg[port].value = CPU_TO_LE16(0); + + udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); + udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; + udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; + udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; + // Call application callback + // to initialize memories or indicate that interface is enabled + UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); + if (!UDI_CDC_ENABLE_EXT(port)) { + return false; + } + udi_cdc_nb_comm_enabled++; + return true; +} + +bool udi_cdc_data_enable(void) +{ + uint8_t port; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; + udi_cdc_nb_data_enabled = 0; +#else + if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { + udi_cdc_nb_data_enabled = 0; + } + port = udi_cdc_nb_data_enabled; +#endif + + // Initialize TX management + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_buf_sel[port] = 0; + udi_cdc_tx_buf_nb[port][0] = 0; + udi_cdc_tx_buf_nb[port][1] = 0; + udi_cdc_tx_sof_num[port] = 0; + udi_cdc_tx_send(port); + + // Initialize RX management + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_buf_sel[port] = 0; + udi_cdc_rx_buf_nb[port][0] = 0; + udi_cdc_rx_pos[port] = 0; + if (!udi_cdc_rx_start(port)) { + return false; + } + udi_cdc_nb_data_enabled++; + if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { + udi_cdc_data_running = true; + } + return true; +} + +void udi_cdc_comm_disable(void) +{ + Assert(udi_cdc_nb_comm_enabled != 0); + udi_cdc_nb_comm_enabled--; +} + +void udi_cdc_data_disable(void) +{ + uint8_t port; + + Assert(udi_cdc_nb_data_enabled != 0); + udi_cdc_nb_data_enabled--; + port = udi_cdc_nb_data_enabled; + UDI_CDC_DISABLE_EXT(port); + udi_cdc_data_running = false; +} + +bool udi_cdc_comm_setup(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + + if (Udd_setup_is_in()) { + // GET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_GET_LINE_CODING: + // Get configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + } + } + } + if (Udd_setup_is_out()) { + // SET Interface Requests + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CDC_SET_LINE_CODING: + // Change configuration of CDC line + if (sizeof(usb_cdc_line_coding_t) != + udd_g_ctrlreq.req.wLength) + return false; // Error for USB host + udd_g_ctrlreq.callback = + udi_cdc_line_coding_received; + udd_g_ctrlreq.payload = + (uint8_t *) & + udi_cdc_line_coding[port]; + udd_g_ctrlreq.payload_size = + sizeof(usb_cdc_line_coding_t); + return true; + case USB_REQ_CDC_SET_CONTROL_LINE_STATE: + // According cdc spec 1.1 chapter 6.2.14 + UDI_CDC_SET_DTR_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_DTE_PRESENT))); + UDI_CDC_SET_RTS_EXT(port, (0 != + (udd_g_ctrlreq.req.wValue + & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); + return true; + } + } + } + return false; // request Not supported +} + +bool udi_cdc_data_setup(void) +{ + return false; // request Not supported +} + +uint8_t udi_cdc_getsetting(void) +{ + return 0; // CDC don't have multiple alternate setting +} + +void udi_cdc_data_sof_notify(void) +{ + static uint8_t port_notify = 0; + + // A call of udi_cdc_data_sof_notify() is done for each port + udi_cdc_tx_send(port_notify); +#if UDI_CDC_PORT_NB != 1 // To optimize code + port_notify++; + if (port_notify >= UDI_CDC_PORT_NB) { + port_notify = 0; + } +#endif +} + + +//------------------------------------------------- +//------- Internal routines to control serial line + +static uint8_t udi_cdc_setup_to_port(void) +{ + uint8_t port; + + switch (udd_g_ctrlreq.req.wIndex & 0xFF) { +#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ + case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) +#undef UDI_CDC_IFACE_COMM_TO_PORT + default: + port = 0; + break; + } + return port; +} + +static void udi_cdc_line_coding_received(void) +{ + uint8_t port = udi_cdc_setup_to_port(); + UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); +} + +static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) +{ + irqflags_t flags; + udd_ep_id_t ep_comm; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Update state + flags = cpu_irq_save(); // Protect udi_cdc_state + if (b_set) { + udi_cdc_state[port] |= bit_mask; + } else { + udi_cdc_state[port] &= ~(unsigned)bit_mask; + } + cpu_irq_restore(flags); + + // Send it if possible and state changed + switch (port) { +#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ + case index: \ + ep_comm = UDI_CDC_COMM_EP_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) +#undef UDI_CDC_PORT_TO_COMM_EP + default: + ep_comm = UDI_CDC_COMM_EP_0; + break; + } + udi_cdc_ctrl_state_notify(port, ep_comm); +} + + +static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + // Send it if possible and state changed + if ((!udi_cdc_serial_state_msg_ongoing[port]) + && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { + // Fill notification message + uid_cdc_state_msg[port].value = udi_cdc_state[port]; + // Send notification message + udi_cdc_serial_state_msg_ongoing[port] = + udd_ep_run(ep, + false, + (uint8_t *) & uid_cdc_state_msg[port], + sizeof(uid_cdc_state_msg[0]), + udi_cdc_serial_state_msg_sent); + } +} + + +static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + UNUSED(status); + + switch (ep) { +#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ + case UDI_CDC_COMM_EP_##iface: \ + port = iface; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) +#undef UDI_CDC_GET_PORT_FROM_COMM_EP + default: + port = 0; + break; + } + + udi_cdc_serial_state_msg_ongoing[port] = false; + + // For the irregular signals like break, the incoming ring signal, + // or the overrun error state, this will reset their values to zero + // and again will not send another notification until their state changes. + udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | + CDC_SERIAL_STATE_RING | + CDC_SERIAL_STATE_FRAMING | + CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); + // Send it if possible and state changed + udi_cdc_ctrl_state_notify(port, ep); +} + + +//------------------------------------------------- +//------- Internal routines to process data transfer + + +static bool udi_cdc_rx_start(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + flags = cpu_irq_save(); + buf_sel_trans = udi_cdc_rx_buf_sel[port]; + if (udi_cdc_rx_trans_ongoing[port] || + (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { + // Transfer already on-going or current buffer no empty + cpu_irq_restore(flags); + return false; + } + + // Change current buffer + udi_cdc_rx_pos[port] = 0; + udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; + + // Start transfer on RX + udi_cdc_rx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + if (udi_cdc_multi_is_rx_ready(port)) { + UDI_CDC_RX_NOTIFY(port); + } + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_OUT_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_OUT + default: + ep = UDI_CDC_DATA_EP_OUT_0; + break; + } + return udd_ep_run(ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); +} + + +static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t buf_sel_trans; + uint8_t port; + + switch (ep) { +#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_OUT_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_OUT_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort reception + return; + } + buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; + if (!n) { + udd_ep_run( ep, + true, + udi_cdc_rx_buf[port][buf_sel_trans], + UDI_CDC_RX_BUFFERS, + udi_cdc_data_received); + return; + } + udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; + udi_cdc_rx_trans_ongoing[port] = false; + udi_cdc_rx_start(port); +} + + +static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) +{ + uint8_t port; + UNUSED(n); + + switch (ep) { +#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ + case UDI_CDC_DATA_EP_IN_##index: \ + port = index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) +#undef UDI_CDC_DATA_EP_IN_TO_PORT + default: + port = 0; + break; + } + + if (UDD_EP_TRANSFER_OK != status) { + // Abort transfer + return; + } + udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; + udi_cdc_tx_both_buf_to_send[port] = false; + udi_cdc_tx_trans_ongoing[port] = false; + udi_cdc_tx_send(port); +} + + +static void udi_cdc_tx_send(uint8_t port) +{ + irqflags_t flags; + uint8_t buf_sel_trans; + bool b_short_packet; + udd_ep_id_t ep; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_trans_ongoing[port]) { + return; // Already on going or wait next SOF to send next data + } + if (udd_is_high_speed()) { + if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { + return; // Wait next SOF to send next data + } + }else{ + if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { + return; // Wait next SOF to send next data + } + } + + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + buf_sel_trans = udi_cdc_tx_buf_sel[port]; + if (!udi_cdc_tx_both_buf_to_send[port]) { + // Send current Buffer + // and switch the current buffer + udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; + }else{ + // Send the other Buffer + // and no switch the current buffer + buf_sel_trans = (buf_sel_trans==0)?1:0; + } + udi_cdc_tx_trans_ongoing[port] = true; + cpu_irq_restore(flags); + + b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); + if (b_short_packet) { + if (udd_is_high_speed()) { + udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); + }else{ + udi_cdc_tx_sof_num[port] = udd_get_frame_number(); + } + }else{ + udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF + } + + // Send the buffer with enable of short packet + switch (port) { +#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ + case index: \ + ep = UDI_CDC_DATA_EP_IN_##index; \ + break; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) +#undef UDI_CDC_PORT_TO_DATA_EP_IN + default: + ep = UDI_CDC_DATA_EP_IN_0; + break; + } + udd_ep_run( ep, + b_short_packet, + udi_cdc_tx_buf[port][buf_sel_trans], + udi_cdc_tx_buf_nb[port][buf_sel_trans], + udi_cdc_data_sent); +} + + +//--------------------------------------------- +//------- Application interface + + +//------- Application interface + +void udi_cdc_ctrl_signal_dcd(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_ctrl_signal_dsr(bool b_set) +{ + udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_signal_framing_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_signal_parity_error(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_signal_overrun(void) +{ + udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); +} + +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); +} + +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) +{ + udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); +} + +void udi_cdc_multi_signal_framing_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); +} + +void udi_cdc_multi_signal_parity_error(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); +} + +void udi_cdc_multi_signal_overrun(uint8_t port) +{ + udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); +} + +bool udi_cdc_multi_is_rx_ready(uint8_t port) +{ +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + uint16_t pos = udi_cdc_rx_pos[port]; + return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]); +} + +bool udi_cdc_is_rx_ready(void) +{ + return udi_cdc_multi_is_rx_ready(0); +} + +int udi_cdc_multi_getc(uint8_t port) +{ + int rx_data = 0; + bool b_databit_9; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_getc_process_one_byte: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return 0; + } + goto udi_cdc_getc_process_one_byte; + } + + // Read data + rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; + udi_cdc_rx_pos[port] = pos+1; + + udi_cdc_rx_start(port); + + if (b_databit_9) { + // Receive MSB + b_databit_9 = false; + rx_data = rx_data << 8; + goto udi_cdc_getc_process_one_byte; + } + return rx_data; +} + +int udi_cdc_getc(void) +{ + return udi_cdc_multi_getc(0); +} + +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) +{ + uint8_t *ptr_buf = (uint8_t *)buf; + iram_size_t copy_nb; + uint16_t pos; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + +udi_cdc_read_buf_loop_wait: + // Check available data + pos = udi_cdc_rx_pos[port]; + buf_sel = udi_cdc_rx_buf_sel[port]; + while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_read_buf_loop_wait; + } + + // Read data + copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); + udi_cdc_rx_pos[port] += copy_nb; + ptr_buf += copy_nb; + size -= copy_nb; + udi_cdc_rx_start(port); + + if (size) { + goto udi_cdc_read_buf_loop_wait; + } + return 0; +} + +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) +{ + return udi_cdc_multi_read_buf(0, buf, size); +} + +bool udi_cdc_multi_is_tx_ready(uint8_t port) +{ + irqflags_t flags; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) { + return true; + } + if (!udi_cdc_tx_both_buf_to_send[port]) { + flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel + if (!udi_cdc_tx_trans_ongoing[port]) { + // No transfer on-going + // then use the other buffer to store data + udi_cdc_tx_both_buf_to_send[port] = true; + udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0; + } + cpu_irq_restore(flags); + } + return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS); +} + +bool udi_cdc_is_tx_ready(void) +{ + return udi_cdc_multi_is_tx_ready(0); +} + +int udi_cdc_multi_putc(uint8_t port, int value) +{ + irqflags_t flags; + bool b_databit_9; + uint8_t buf_sel; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); + +udi_cdc_putc_process_one_byte: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return false; + } + goto udi_cdc_putc_process_one_byte; + } + + // Write value + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; + cpu_irq_restore(flags); + + if (b_databit_9) { + // Send MSB + b_databit_9 = false; + value = value >> 8; + goto udi_cdc_putc_process_one_byte; + } + return true; +} + +int udi_cdc_putc(int value) +{ + return udi_cdc_multi_putc(0, value); +} + +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) +{ + irqflags_t flags; + uint8_t buf_sel; + uint16_t buf_nb; + iram_size_t copy_nb; + uint8_t *ptr_buf = (uint8_t *)buf; + +#if UDI_CDC_PORT_NB == 1 // To optimize code + port = 0; +#endif + + if (9 == udi_cdc_line_coding[port].bDataBits) { + size *=2; + } + +udi_cdc_write_buf_loop_wait: + // Check available space + if (!udi_cdc_multi_is_tx_ready(port)) { + if (!udi_cdc_data_running) { + return size; + } + goto udi_cdc_write_buf_loop_wait; + } + + // Write values + flags = cpu_irq_save(); + buf_sel = udi_cdc_tx_buf_sel[port]; + buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; + copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; + if (copy_nb>size) { + copy_nb = size; + } + memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); + udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; + cpu_irq_restore(flags); + + // Update buffer pointer + ptr_buf = ptr_buf + copy_nb; + size -= copy_nb; + + if (size) { + goto udi_cdc_write_buf_loop_wait; + } + + return 0; +} + +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) +{ + return udi_cdc_multi_write_buf(0, buf, size); +} + +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..de7ea7bdd3faef37ce412e76f967ee7dc43b26a6 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc.h @@ -0,0 +1,764 @@ +/** + * \file + * + * \brief USB Device Communication Device Class (CDC) interface definitions. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_H_ +#define _UDI_CDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_cdc.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" + +// Check the number of port +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif +#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) +# error UDI_CDC_PORT_NB must be between 1 and 7 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_udc + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; +extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; +//@} + +/** + * \ingroup udi_cdc_group + * \defgroup udi_cdc_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \brief Communication Class interface descriptor + * + * Interface descriptor with associated functional and endpoint + * descriptors for the CDC Communication Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! CDC Header functional descriptor + usb_cdc_hdr_desc_t header; + //! CDC Abstract Control Model functional descriptor + usb_cdc_acm_desc_t acm; + //! CDC Union functional descriptor + usb_cdc_union_desc_t union_desc; + //! CDC Call Management functional descriptor + usb_cdc_call_mgmt_desc_t call_mgmt; + //! Notification endpoint descriptor + usb_ep_desc_t ep_notify; +} udi_cdc_comm_desc_t; + + +/** + * \brief Data Class interface descriptor + * + * Interface descriptor with associated endpoint descriptors for the + * CDC Data Class interface. + */ +typedef struct { + //! Standard interface descriptor + usb_iface_desc_t iface; + //! Data IN/OUT endpoint descriptors + usb_ep_desc_t ep_in; + usb_ep_desc_t ep_out; +} udi_cdc_data_desc_t; + + +//! CDC communication endpoints size for all speeds +#define UDI_CDC_COMM_EP_SIZE 64 +//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) +#define UDI_CDC_DATA_EPS_FS_SIZE 64 +//! CDC data endpoints size for HS speed (512B only) +#define UDI_CDC_DATA_EPS_HS_SIZE 512 + +/** + * \name Content of interface descriptors + * Up to 7 CDC interfaces can be implemented on a USB device. + */ +//@{ +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_0 +#define UDI_CDC_IAD_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_0 +#define UDI_CDC_COMM_STRING_ID_0 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_0 +#define UDI_CDC_DATA_STRING_ID_0 0 +#endif +#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) +#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) +#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) +#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_1 +#define UDI_CDC_IAD_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_1 +#define UDI_CDC_COMM_STRING_ID_1 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_1 +#define UDI_CDC_DATA_STRING_ID_1 0 +#endif +#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) +#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) +#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) +#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_2 +#define UDI_CDC_IAD_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_2 +#define UDI_CDC_COMM_STRING_ID_2 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_2 +#define UDI_CDC_DATA_STRING_ID_2 0 +#endif +#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) +#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) +#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) +#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_3 +#define UDI_CDC_IAD_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_3 +#define UDI_CDC_COMM_STRING_ID_3 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_3 +#define UDI_CDC_DATA_STRING_ID_3 0 +#endif +#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) +#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) +#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) +#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_4 +#define UDI_CDC_IAD_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_4 +#define UDI_CDC_COMM_STRING_ID_4 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_4 +#define UDI_CDC_DATA_STRING_ID_4 0 +#endif +#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) +#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) +#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) +#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_5 +#define UDI_CDC_IAD_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_5 +#define UDI_CDC_COMM_STRING_ID_5 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_5 +#define UDI_CDC_DATA_STRING_ID_5 0 +#endif +#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) +#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) +#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) +#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) + +//! By default no string associated to these interfaces +#ifndef UDI_CDC_IAD_STRING_ID_6 +#define UDI_CDC_IAD_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_COMM_STRING_ID_6 +#define UDI_CDC_COMM_STRING_ID_6 0 +#endif +#ifndef UDI_CDC_DATA_STRING_ID_6 +#define UDI_CDC_DATA_STRING_ID_6 0 +#endif +#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) +#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) +#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) +#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) +//@} + + +//! Content of CDC IAD interface descriptor for all speeds +#define UDI_CDC_IAD_DESC(port) { \ + .bLength = sizeof(usb_iad_desc_t),\ + .bDescriptorType = USB_DT_IAD,\ + .bInterfaceCount = 2,\ + .bFunctionClass = CDC_CLASS_COMM,\ + .bFunctionSubClass = CDC_SUBCLASS_ACM,\ + .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ + .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ + } + +//! Content of CDC COMM interface descriptor for all speeds +#define UDI_CDC_COMM_DESC(port) { \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = CDC_CLASS_COMM,\ + .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ + .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ + .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ + .header.bDescriptorType = CDC_CS_INTERFACE,\ + .header.bDescriptorSubtype = CDC_SCS_HEADER,\ + .header.bcdCDC = LE16(0x0110),\ + .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ + .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ + .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ + .call_mgmt.bmCapabilities = \ + CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ + .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ + .acm.bDescriptorType = CDC_CS_INTERFACE,\ + .acm.bDescriptorSubtype = CDC_SCS_ACM,\ + .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ + .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ + .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ + .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ + .ep_notify.bLength = sizeof(usb_ep_desc_t),\ + .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ + .ep_notify.bInterval = 0x10,\ + .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ + .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ + .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ + } + +//! Content of CDC DATA interface descriptors +#define UDI_CDC_DATA_DESC_COMMON \ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 2,\ + .iface.bInterfaceClass = CDC_CLASS_DATA,\ + .iface.bInterfaceSubClass = 0,\ + .iface.bInterfaceProtocol = 0,\ + .ep_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_in.bInterval = 0,\ + .ep_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_out.bInterval = 0, + +#define UDI_CDC_DATA_DESC_FS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +#define UDI_CDC_DATA_DESC_HS(port) { \ + UDI_CDC_DATA_DESC_COMMON \ + .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ + .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ + .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ + .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ + .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ + } + +//@} + +/** + * \ingroup udi_group + * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer and control data + * to/from USB CDC endpoint. + * + * See \ref udi_cdc_quickstart. + * @{ + */ + +/** + * \name Interface for application with single CDC interface support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dcd(bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_ctrl_signal_dsr(bool b_set); + +/** + * \brief Notify a framing error + */ +void udi_cdc_signal_framing_error(void); + +/** + * \brief Notify a parity error + */ +void udi_cdc_signal_parity_error(void); + +/** + * \brief Notify a overrun + */ +void udi_cdc_signal_overrun(void); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_is_rx_ready(void); + +/** + * \brief Waits and gets a value on CDC line + * + * \return value read on CDC line + */ +int udi_cdc_getc(void); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param buf Values read + * \param size Number of value read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_is_tx_ready(void); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_putc(int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); +//@} + +/** + * \name Interface for application with multi CDC interfaces support + */ +//@{ + +/** + * \brief Notify a state change of DCD signal + * + * \param port Communication port number to manage + * \param b_set DCD is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); + +/** + * \brief Notify a state change of DSR signal + * + * \param port Communication port number to manage + * \param b_set DSR is enabled if true, else disabled + */ +void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); + +/** + * \brief Notify a framing error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_framing_error(uint8_t port); + +/** + * \brief Notify a parity error + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_parity_error(uint8_t port); + +/** + * \brief Notify a overrun + * + * \param port Communication port number to manage + */ +void udi_cdc_multi_signal_overrun(uint8_t port); + +/** + * \brief This function checks if a character has been received on the CDC line + * + * \param port Communication port number to manage + * + * \return \c 1 if a byte is ready to be read. + */ +bool udi_cdc_multi_is_rx_ready(uint8_t port); + +/** + * \brief Waits and gets a value on CDC line + * + * \param port Communication port number to manage + * + * \return value read on CDC line + */ +int udi_cdc_multi_getc(uint8_t port); + +/** + * \brief Reads a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values read + * \param size Number of values read + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); + +/** + * \brief This function checks if a new character sent is possible + * The type int is used to support scanf redirection from compiler LIB. + * + * \param port Communication port number to manage + * + * \return \c 1 if a new character can be sent + */ +bool udi_cdc_multi_is_tx_ready(uint8_t port); + +/** + * \brief Puts a byte on CDC line + * The type int is used to support printf redirection from compiler LIB. + * + * \param port Communication port number to manage + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int udi_cdc_multi_putc(uint8_t port, int value); + +/** + * \brief Writes a RAM buffer on CDC line + * + * \param port Communication port number to manage + * \param buf Values to write + * \param size Number of value to write + * + * \return the number of data remaining + */ +iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); +//@} + +//@} + +/** + * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) + * + * This is the quick start guide for the \ref udi_cdc_group + * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section udi_cdc_basic_use_case Basic use case + * In this basic use case, the "USB CDC (Single Interface Device)" module is used + * with only one communication port. + * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases + * "Advanced use cases". + * + * \section udi_cdc_basic_use_case_setup Setup steps + * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_cdc_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_cdc_basic_use_case_usage Usage steps + * + * \subsection udi_cdc_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); + * #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); + * #define UDI_CDC_LOW_RATE + * + * #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 + * + * #include "udi_cdc_conf.h" // At the end of conf_usb.h file + * \endcode + * + * Add to application C-file: + * \code + * static bool my_flag_autorize_cdc_transfert = false; + * bool my_callback_cdc_enable(void) + * { + * my_flag_autorize_cdc_transfert = true; + * return true; + * } + * void my_callback_cdc_disable(void) + * { + * my_flag_autorize_cdc_transfert = false; + * } + * + * void task(void) + * { + * if (my_flag_autorize_cdc_transfert) { + * udi_cdc_putc('A'); + * udi_cdc_getc(); + * } + * } + * \endcode + * + * \subsection udi_cdc_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device CDC configuration: + * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode + * \note The USB serial number is mandatory when a CDC interface is used. + * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() + * extern bool my_callback_cdc_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB CDC interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_CDC_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the data transfer on CDC interface are authorized. + * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() + * extern void my_callback_cdc_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function + * is called. Thus, the data transfer must be stopped on CDC interface. + * - \code #define UDI_CDC_LOW_RATE \endcode + * \note Define it when the transfer CDC Device to Host is a low rate + * (<512000 bauds) to reduce CDC buffers size. + * - \code #define UDI_CDC_DEFAULT_RATE 115200 + * #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 + * #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE + * #define UDI_CDC_DEFAULT_DATABITS 8 \endcode + * \note Default configuration of communication port at startup. + * -# Send or wait data on CDC line: + * - \code // Waits and gets a value on CDC line + * int udi_cdc_getc(void); + * // Reads a RAM buffer on CDC line + * iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size); + * // Puts a byte on CDC line + * int udi_cdc_putc(int value); + * // Writes a RAM buffer on CDC line + * iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode + * + * \section udi_cdc_use_cases Advanced use cases + * For more advanced use of the UDI CDC module, see the following use cases: + * - \subpage udi_cdc_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_4 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_cdc_use_case_composite CDC in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB CDC (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_cdc_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_cdc_basic_use_case "basic use case" must be followed. + * + * \section udi_cdc_use_case_composite_usage Usage steps + * + * \subsection udi_cdc_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * #define USB_DEVICE_NB_INTERFACE (X+2) + * #define USB_DEVICE_MAX_EP (X+3) + * + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 + * + * #define UDI_COMPOSITE_DESC_T \ + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * #define UDI_COMPOSITE_DESC_FS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * #define UDI_COMPOSITE_DESC_HS \ + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * #define UDI_COMPOSITE_API \ + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... + * \endcode + * + * \subsection udi_cdc_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + * // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + * // - 64 for a high speed device + * #define USB_DEVICE_EP_CTRL_SIZE 64 + * // Total Number of interfaces on this USB device. + * // Add 2 for CDC. + * #define USB_DEVICE_NB_INTERFACE (X+2) + * // Total number of endpoints on this USB device. + * // This must include each endpoint for each interface. + * // Add 3 for CDC. + * #define USB_DEVICE_MAX_EP (X+3) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the CDC. + * // The endpoint numbers starting from 1. + * #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX + * #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX + * #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint + * // The interface index of an interface starting from 0 + * #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 + * #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + * #define UDI_COMPOSITE_DESC_T \ + * ... + * usb_iad_desc_t udi_cdc_iad; \ + * udi_cdc_comm_desc_t udi_cdc_comm; \ + * udi_cdc_data_desc_t udi_cdc_data; \ + * ... + * // USB Interfaces descriptor value for Full Speed + * #define UDI_COMPOSITE_DESC_FS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ + * ... + * // USB Interfaces descriptor value for High Speed + * #define UDI_COMPOSITE_DESC_HS \ + * ... + * .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ + * .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ + * .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ + * ... + * // USB Interface APIs + * #define UDI_COMPOSITE_API \ + * ... + * &udi_api_cdc_comm, \ + * &udi_api_cdc_data, \ + * ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines.\n + * Also, the CDC requires a USB Interface Association Descriptor (IAD) for + * composite device. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..69a5ff1589cadab5f813cd55737c1d94b329411c --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Default CDC configuration for a USB Device with a single interface + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_CDC_CONF_H_ +#define _UDI_CDC_CONF_H_ + +#include "usb_protocol_cdc.h" +#include "conf_usb.h" + +#ifndef UDI_CDC_PORT_NB +# define UDI_CDC_PORT_NB 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup udi_cdc_group_single_desc + * @{ + */ + +//! Control endpoint size (Endpoint 0) +#define USB_DEVICE_EP_CTRL_SIZE 64 + +#if XMEGA +/** + * \name Endpoint configuration on XMEGA + * The XMEGA supports a IN and OUT endpoint with the same number endpoint, + * thus XMEGA can support up to 7 CDC interfaces. + */ +//@{ +#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint +//! 2 endpoints numbers used per CDC interface +#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) +//@} + +#else + +/** + * \name Default endpoint configuration + * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. + */ +//@{ +# if UDI_CDC_PORT_NB > 2 +# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints. +# endif +#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint +#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX +#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX +#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint +//! 3 endpoints used per CDC interface +#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) +//@} + +#endif + +/** + * \name Default Interface numbers + */ +//@{ +#define UDI_CDC_COMM_IFACE_NUMBER_0 0 +#define UDI_CDC_DATA_IFACE_NUMBER_0 1 +#define UDI_CDC_COMM_IFACE_NUMBER_1 2 +#define UDI_CDC_DATA_IFACE_NUMBER_1 3 +#define UDI_CDC_COMM_IFACE_NUMBER_2 4 +#define UDI_CDC_DATA_IFACE_NUMBER_2 5 +#define UDI_CDC_COMM_IFACE_NUMBER_3 6 +#define UDI_CDC_DATA_IFACE_NUMBER_3 7 +#define UDI_CDC_COMM_IFACE_NUMBER_4 8 +#define UDI_CDC_DATA_IFACE_NUMBER_4 9 +#define UDI_CDC_COMM_IFACE_NUMBER_5 10 +#define UDI_CDC_DATA_IFACE_NUMBER_5 11 +#define UDI_CDC_COMM_IFACE_NUMBER_6 12 +#define UDI_CDC_DATA_IFACE_NUMBER_6 13 +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_CDC_CONF_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..e90e7b42c21b0128d6939b88432fdb26af6dc679 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c @@ -0,0 +1,225 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single interface CDC + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_cdc.h" + + +/** + * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface CDC. + * + * It is ready to use and do not require more definition. + * + * @{ + */ + +//! Two interfaces for a CDC device +#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) + +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), +#if UDI_CDC_PORT_NB > 1 + .bDeviceClass = 0, +#else + .bDeviceClass = CDC_CLASS_DEVICE, +#endif + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; +#if UDI_CDC_PORT_NB == 1 + udi_cdc_comm_desc_t udi_cdc_comm_0; + udi_cdc_data_desc_t udi_cdc_data_0; +#else +# define UDI_CDC_DESC_STRUCTURE(index, unused) \ + usb_iad_desc_t udi_cdc_iad_##index; \ + udi_cdc_comm_desc_t udi_cdc_comm_##index; \ + udi_cdc_data_desc_t udi_cdc_data_##index; + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) +# undef UDI_CDC_DESC_STRUCTURE +#endif +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for full and high speed +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, +#else +# define UDI_CDC_DESC_FS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) +# undef UDI_CDC_DESC_FS +#endif +}; + +#ifdef USB_DEVICE_HS_SUPPORT +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), +#if UDI_CDC_PORT_NB == 1 + .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, + .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, +#else +# define UDI_CDC_DESC_HS(index, unused) \ + .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ + .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ + .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) +# undef UDI_CDC_DESC_HS +#endif +}; +#endif + +/** + * \name UDC structures which content all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { +# define UDI_CDC_API(index, unused) \ + &udi_api_cdc_comm, \ + &udi_api_cdc_data, + MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) +# undef UDI_CDC_API +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; +#ifdef USB_DEVICE_HS_SUPPORT +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..ec6235af4cd6e0137e408f3601a43ff5050632d9 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/class/cdc/usb_protocol_cdc.h @@ -0,0 +1,315 @@ +/** + * \file + * + * \brief USB Communication Device Class (CDC) protocol definitions + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _USB_PROTOCOL_CDC_H_ +#define _USB_PROTOCOL_CDC_H_ + +#include "compiler.h" + +/** + * \ingroup usb_protocol_group + * \defgroup cdc_protocol_group Communication Device Class Definitions + * @{ + */ + +/** + * \name Possible values of class + */ +//@{ +#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class +#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface +#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface +//@} + +//! \name USB CDC Subclass IDs +//@{ +#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model +#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model +#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model +#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model +#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model +#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model +#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model +//@} + +//! \name USB CDC Communication Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands +//@} + +//! \name USB CDC Data Interface Protocol IDs +//@{ +#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI +#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC +#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent +#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol +#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol +#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor +#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures +#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control +#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN +#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands +#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver +/** + * \brief Describes the Protocol Unit Functional Descriptors [sic] + * on Communication Class Interface + */ +#define CDC_PROTOCOL_PUFD 0xFE +//@} + +//! \name USB CDC Functional Descriptor Types +//@{ +#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor +#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor +//@} + +//! \name USB CDC Functional Descriptor Subtypes +//@{ +#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor +#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management +#define CDC_SCS_ACM 0x02 //!< Abstract Control Management +#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor +//@} + +//! \name USB CDC Request IDs +//@{ +#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 +#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 +#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 +#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 +#define USB_REQ_CDC_SET_HOOK_STATE 0x11 +#define USB_REQ_CDC_PULSE_SETUP 0x12 +#define USB_REQ_CDC_SEND_PULSE 0x13 +#define USB_REQ_CDC_SET_PULSE_TIME 0x14 +#define USB_REQ_CDC_RING_AUX_JACK 0x15 +#define USB_REQ_CDC_SET_LINE_CODING 0x20 +#define USB_REQ_CDC_GET_LINE_CODING 0x21 +#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 +#define USB_REQ_CDC_SEND_BREAK 0x23 +#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 +#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 +#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 +#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 +#define USB_REQ_CDC_SET_LINE_PARMS 0x34 +#define USB_REQ_CDC_GET_LINE_PARMS 0x35 +#define USB_REQ_CDC_DIAL_DIGITS 0x36 +#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 +#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 +#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 +#define USB_REQ_CDC_GET_PROFILE 0x3A +#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 +#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 +#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 +#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 +#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 +#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 +// Added bNotification codes according cdc spec 1.1 chapter 6.3 +#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 +#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 +#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 +//@} + +/* + * Need to pack structures tightly, or the compiler might insert padding + * and violate the spec-mandated layout. + */ +COMPILER_PACK_SET(1) + +//! \name USB CDC Descriptors +//@{ + + +//! CDC Header Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + le16_t bcdCDC; +} usb_cdc_hdr_desc_t; + +//! CDC Call Management Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} usb_cdc_call_mgmt_desc_t; + +//! CDC ACM Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} usb_cdc_acm_desc_t; + +//! CDC Union Functional Descriptor +typedef struct { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +} usb_cdc_union_desc_t; + + +//! \name USB CDC Call Management Capabilities +//@{ +//! Device handles call management itself +#define CDC_CALL_MGMT_SUPPORTED (1 << 0) +//! Device can send/receive call management info over a Data Class interface +#define CDC_CALL_MGMT_OVER_DCI (1 << 1) +//@} + +//! \name USB CDC ACM Capabilities +//@{ +//! Device supports the request combination of +//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. +#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) +//! Device supports the request combination of +//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, +//! and the notification Serial_State. +#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) +//! Device supports the request Send_Break +#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) +//! Device supports the notification Network_Connection. +#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) +//@} +//@} + +//! \name USB CDC line control +//@{ + +//! \name USB CDC line coding +//@{ +//! Line Coding structure +typedef struct { + le32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; +//! Possible values of bCharFormat +enum cdc_char_format { + CDC_STOP_BITS_1 = 0, //!< 1 stop bit + CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits + CDC_STOP_BITS_2 = 2, //!< 2 stop bits +}; +//! Possible values of bParityType +enum cdc_parity { + CDC_PAR_NONE = 0, //!< No parity + CDC_PAR_ODD = 1, //!< Odd parity + CDC_PAR_EVEN = 2, //!< Even parity + CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) + CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) +}; +//@} + +//! \name USB CDC control signals +//! spec 1.1 chapter 6.2.14 +//@{ + +//! Control signal structure +typedef struct { + uint16_t value; +} usb_cdc_control_signal_t; + +//! \name Possible values in usb_cdc_control_signal_t +//@{ +//! Carrier control for half duplex modems. +//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. +//! The device ignores the value of this bit +//! when operating in full duplex mode. +#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) +//! Indicates to DCE if DTE is present or not. +//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. +#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) +//@} +//@} + + +//! \name USB CDC notification message +//@{ + +typedef struct { + uint8_t bmRequestType; + uint8_t bNotification; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_cdc_notify_msg_t; + +//! \name USB CDC serial state +//@{* + +//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) +typedef struct { + usb_cdc_notify_msg_t header; + le16_t value; +} usb_cdc_notify_serial_state_t; + +//! \name Possible values in usb_cdc_notify_serial_state_t +//@{ +#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) +#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) +#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) +#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) +#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) +#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) +#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) +//@} +//! @} + +//! @} + +COMPILER_PACK_RESET() + +//! @} + +#endif // _USB_PROTOCOL_CDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c new file mode 100644 index 0000000000000000000000000000000000000000..744ea1bf0057500eed18bb849a005c608de15f39 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1090 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h new file mode 100644 index 0000000000000000000000000000000000000000..2929422258c5d497821234e5d3941220f79b47c1 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc.h @@ -0,0 +1,726 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr and \ref clk_group clock services. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * Add to the initialization code: + * \code + * sysclk_init(); + * irq_initialize_vectors(); + * cpu_irq_enable(); + * board_init(); + * sleepmgr_init(); // Optional + * \endcode + * Add to the main IDLE loop: + * \code + * sleepmgr_enter_sleep(); // Optional + * \endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_VENDOR_ID 0x03EB + * #define USB_DEVICE_PRODUCT_ID 0xXXXX + * #define USB_DEVICE_MAJOR_VERSION 1 + * #define USB_DEVICE_MINOR_VERSION 0 + * #define USB_DEVICE_POWER 100 + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED + * + * #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); + * \endcode + * + * Add to application C-file: + * \code + * void usb_init(void) + * { + * udc_start(); + * } + * + * void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + * #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + * // Product ID (Atmel PID referenced in usb_atmel.h) + * #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + * // Major version of the device + * #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + * // Minor version of the device + * #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + * // Maximum device power (mA) + * #define USB_DEVICE_POWER 100 // Type 9-bits + * // USB attributes to enable features + * #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high) + * extern void my_vbus_action(bool b_high); \endcode + * \note This callback is called when USB Device cable is plugged or unplugged. + * -# Call the USB device stack start function to enable stack: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + * -# Connect or disconnect USB device according to Vbus state: + * - \code void my_vbus_action(bool b_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } \endcode + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + * // Configuration based on internal RC: + * // USB clock need of 48Mhz + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * \endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * \endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + * // Configuration based on 12MHz external OSC: + * #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + * #define CONFIG_PLL1_MUL 8 + * #define CONFIG_PLL1_DIV 2 + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + * // CPU clock need of clock > 25MHz to run with USBC + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 + * \endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + * // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL 16 + * #define CONFIG_PLL1_DIV 2 + * // USB Clock Source Options (Fusb = FpllX / USB_div) + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 2 + * \endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * \endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + * // USB Clock Source fixed at UPLL. + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + * #define CONFIG_USBCLK_DIV 1 + * \endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + * #if // Low speed + * #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // Full speed + * // #define USB_DEVICE_LOW_SPEED + * // #define USB_DEVICE_HS_SUPPORT + * + * #elif // High speed + * // #define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT + * + * #endif + * \endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + * #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + * #define USB_DEVICE_PRODUCT_NAME "Product name" + * #define USB_DEVICE_SERIAL_NAME "12...EF" + * \endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + * #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + * #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + * #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR \ + * (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); + * \endcode + * + * Add to application C-file: + * \code + * void my_callback_remotewakeup_enable(void) + * { + * // Enable application wakeup events (e.g. enable GPIO interrupt) + * } + * void my_callback_remotewakeup_disable(void) + * { + * // Disable application wakeup events (e.g. disable GPIO interrupt) + * } + * + * void my_interrupt_event(void) + * { + * udc_remotewakeup(); + * } + * \endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + * extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + * #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + * extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_4 Self power application recommendations + * + * In this use case, the USB device self power feature is enabled. + * To be USB compliance, the SELF power application requires to manage Vbus event, + * because the USB device D+/- pull-up must be disabled if the USB cable is unplugged + * (unplug = Vbus not present, pull-up disable = \ref udd_detach()). + * This use case requires that Atmel products includes a Vbus monitoring, else + * see \ref udc_include_vbus_monitoring function documentation for more example. + * + * \section udc_use_case_4_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_4_usage Usage steps + * + * \subsection udc_use_case_4_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_vbus_action(bool b_vbus_high) + * { + * if (b_high) { + * // Attach USB Device + * udc_attach(); + * } else { + * // Vbus not present + * udc_detach(); + * } + * } + * \endcode + * + * \subsection udc_use_case_4_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for USB device SELF power device: + * - \code // Authorizes the SELF power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode + * - \code // Define callback called when the Vbus level change + * #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high) + * extern void user_callback_vbus_action(bool b_vbus_high); \endcode + * -# Signal the USB device presence on USB line + * - \code udc_attach(); \endcode + * -# Remove signal of the USB device presence on USB line + * - \code udc_detach(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void) + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void) + * \endcode + * + * Add to application C-file: + * \code + * void user_callback_suspend_action(void) + * { + * // Disable hardware component to reduce power consumption + * } + * void user_callback_resume_action(void) + * { + * // Re-enable hardware component + * } + * \endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + * #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + * #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + * extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + * #define UDC_RESUME_EVENT() user_callback_resume_action() + * extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + * { + * turn_off_components(); + * } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + * #define USB_DEVICE_SERIAL_NAME + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + * extern uint8_t serial_number[]; + * \endcode + * + * Add to application C-file: + * \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + * #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + * #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + * extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + * uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + * + * void init_build_usb_serial_number(void) + * { + * serial_number[0] = 'A'; + * serial_number[1] = 'B'; + * ... + * serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + * } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..294ee10597edb31e9d4292f3e4e9087dd3c17c14 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h new file mode 100644 index 0000000000000000000000000000000000000000..cba4814d25022bef8d95cc00de6b7bcd0af4a8be --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udd.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h new file mode 100644 index 0000000000000000000000000000000000000000..48287f2792aed27aee1330d282862a88d2bb9a36 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/udc/udi.h @@ -0,0 +1,130 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h new file mode 100644 index 0000000000000000000000000000000000000000..8d547b4f745253c16799d70844be3cb9f7550a8b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,185 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0d3f2e2ef343f39d4334c475681c74471fb47e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,410 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..088d96b27f2872de9e626998d39e127417fb0678 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibilty accross compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 0000000000000000000000000000000000000000..35ed96dac210f340759403c49b29246144a3753f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + * ISR(FOO_vect) + * { + * ... + * } + * \endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in new file mode 100644 index 0000000000000000000000000000000000000000..1e9f0488c132442e28ae3545fee2d110999068c0 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/make/Makefile.avr.in @@ -0,0 +1,459 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# 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 +# EXPRESSLY AND SPECIFICALLY 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. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: $(target) $(project).hex $(project).lss $(project).sym +endif +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h new file mode 100644 index 0000000000000000000000000000000000000000..6463c881ca2026ff876e80ebfd7eb02d03abd7b2 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/parts.h @@ -0,0 +1,880 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c new file mode 100644 index 0000000000000000000000000000000000000000..367c23e1776316ef6511c6a9c57d4d2dfb3202bd --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/read.c @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && XMEGA) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c new file mode 100644 index 0000000000000000000000000000000000000000..9723a944c78769180dfe25113c791f1f4a1854a7 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.c @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief USB CDC Standard I/O Serial Management. + * + * This module defines support routines for a stdio serial interface to the + * Atmel Software Framework (ASF) common USB CDC service. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + + +#include "stdio_usb.h" + +static bool stdio_usb_interface_enable = false; + +int stdio_usb_putchar (volatile void * unused, char data) +{ + /* A negative return value should be used to indicate that data + * was not written, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + return 0; // -1 + } + + return udi_cdc_putc(data) ? 0 : -1; +} + +void stdio_usb_getchar (void volatile * unused, char *data) +{ + /* A negative return value should be used to indicate that data + * was not read, but this doesn't seem to work with GCC libc. + */ + if (!stdio_usb_interface_enable) { + *data = 0; // -1 + return; + } + + *data = (char)udi_cdc_getc(); +} + +void stdio_usb_vbus_event(bool b_high) +{ + if (b_high) { + // Attach USB Device + udc_attach(); + } else { + // VBUS not present + udc_detach(); + } +} + +bool stdio_usb_enable(void) +{ + stdio_usb_interface_enable = true; + return true; +} + +void stdio_usb_disable(void) +{ + stdio_usb_interface_enable = false; +} + +void stdio_usb_init(void) +{ + stdio_base = NULL; + ptr_put = stdio_usb_putchar; + ptr_get = stdio_usb_getchar; + + /* + * Start and attach USB CDC device interface for devices with + * integrated USB interfaces. Assume the VBUS is present if + * VBUS monitoring is not available. + */ + udc_start (); + + if (!udc_include_vbus_monitoring()) { + stdio_usb_vbus_event(true); + } + +#if defined(__GNUC__) +# if XMEGA + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +#endif +} + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h new file mode 100644 index 0000000000000000000000000000000000000000..d61a477fc03b6768faee93265e6c178d0fa4ccda --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/stdio_usb/stdio_usb.h @@ -0,0 +1,128 @@ +/** + * \file + * + * \brief USB Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial + * interface on AVR devices. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _stdio_usb_h_ +#define _stdio_usb_h_ + +/** + * \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Standard I/O (stdio) management component that implements a stdio + * USB CDC interface on AVR devices. + * + * \{ + */ + +#include + +#include + +#include +#include + +extern int _write (char c, int *f); +extern int _read (int *f); + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Sends a character with the USART. + * + * \param usart Base address of the USART instance. + * \param data Character to write. + * + * \return Status. + * \retval 0 The character was written. + * \retval -1 The function timed out before the transmitter became ready. + */ +int stdio_usb_putchar (volatile void * usart, char data); + +/*! \brief Waits until a character is received, and returns it. + * + * \param usart Base address of the USART instance. + * \param data Data to read + * + * \return Nothing. + */ +void stdio_usb_getchar (void volatile * usart, char * data); + +/*! \brief Callback for VBUS level change event. + * + * \param b_high 1 if VBus is present + * + * \return Nothing. + */ +void stdio_usb_vbus_event (bool b_high); + +/*! \brief Enables the stdio in USB Serial Mode. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool stdio_usb_enable(void); + +/*! \brief Disables the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_disable(void); + +/*! \brief Initializes the stdio in USB Serial Mode. + * + * \return Nothing. + */ +void stdio_usb_init(void); + +/** + * \} + */ + +#endif // _stdio_usb_h_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c new file mode 100644 index 0000000000000000000000000000000000000000..97a65c0182520d6d57809473fe5a8e9c0d5c134e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/utils/stdio/write.c @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA) + +int _write (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_write (int file, char * ptr, int len); + +int __attribute__((weak)) +_write (int file, char * ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && XMEGA) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h new file mode 100644 index 0000000000000000000000000000000000000000..780b61f88f29fca76ba9f7c70d372bed61fae3a5 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/board.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 + #include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c new file mode 100644 index 0000000000000000000000000000000000000000..62dec1ef33ffeb0f3427f12ce299467051fbbc76 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/init.c @@ -0,0 +1,18 @@ +/** + * \file + * + * \brief User board initialization template + * + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d29e167b05ce4a6c0cc54204b0af64fd3372ca --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/boards/user_board/user_board.h @@ -0,0 +1,37 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h new file mode 100644 index 0000000000000000000000000000000000000000..00d39f0d843a8ba4695c156d09c16fed4ab8c063 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/genclk.h @@ -0,0 +1,176 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4ab0329798be60a8d35e7568e3ea3482bb16f --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..386eb40c4d4e989740ac38642609e041e7a2a07b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..e628c993b9fe1ca12b7484f2a1046ee63e721f3b --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/sysclk.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h new file mode 100644 index 0000000000000000000000000000000000000000..bdb17fa0127f8422ed333fa81173e61aa2893332 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/osc.h @@ -0,0 +1,461 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) + || (ref_id == OSC_ID_USBSOF)); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); + } +#endif + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h new file mode 100644 index 0000000000000000000000000000000000000000..0055b2b21bb60520d4dabf251f13da9caf52997e --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/pll.h @@ -0,0 +1,262 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c new file mode 100644 index 0000000000000000000000000000000000000000..db7b720849d1b1f56b7ed44547f1495036577ae4 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.c @@ -0,0 +1,244 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h new file mode 100644 index 0000000000000000000000000000000000000000..6acd0d0a6fd2a62446ac567100067ce575ac6430 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1393 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / (2 ^ BUS_div) + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + * #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + * #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + * #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + * #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + * \endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + * #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + * \endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * \endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + * #define CONFIG_OSC_RC32_CAL 48000000UL + * #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + * \endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; + + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..a681ca82ccec93b36fb7e4af3614950e946290d8 --- /dev/null +++ b/DSTAT-temp/src/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/xmega/drivers/asf/common/services/delay/delay.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * 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 + * EXPRESSLY AND SPECIFICALLY 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. + * + * \asf_license_stop + * + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */