/** * \file * * \brief MEGA-1284P Xplained Example * * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. * * \asf_license_start * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel microcontroller product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * \asf_license_stop * */ /** * \mainpage * \section board MEGA-1284P Xplained board * \image html kit_front.JPG * \section intro Introduction * This example demonstrates some of the basic features of the MEGA-1284P * Xplained kit. This includes sleep modes, reading the light sensor * and the ntc sensor. * * \section files Files: * - mega_1284p_xplained_example.c: MEGA-1284P Xplained example application * - mega_1284p_xplained_example.h: MEGA-1284P Xplained example header file * - init.c: Initialization driver * - init.h: Initialization driver * - usart.c: USART driver * - usart.h: USART driver * * \section exampledescription Brief description of the example application * The example application have two main modes: \ref demo_mode "demo mode" * or \ref terminal_mode "terminal mode". * Please refer to the \ref application_description "detailed description" * for more information. * * \section compinfo Compilation Info * This software was written for the GNU GCC * and IAR for AVR. \n * Other compilers may or may not work. * * \section contactinfo Contact Information * For further information, visit * Atmel.\n */ /** * \defgroup mega_1284p_xplained_group MEGA-1284P Xplained example application * * \section application_description Description of the example * This is the example application used to demonstrate the MEGA-1284P Xplained * kit. Basically it has two main modes of operation: demo mode or * terminal mode. * \subsection application_flowchart Example application flowchart * \image html application_flowchart.JPG * \subsection demo_mode Demo mode * This mode lets the user select in which mode the ATmega1284P should operate: * Active, power-save (with the 32kHz crystal connected to the TOSC pins * enabled) or power-down. The user can easily measure the power consumption * in the different modes by connecting an ampere meter to the two-pins power * header. Please refer to the hardware user guide for more details. * * The user can also try out capacitive touch sensing by pushing the QTB0 touch * button on the board. LED1 will turn on when QTB0 is touched and switch off * whenever QTB0 is not touched. * * By shorting MISO (pin 7) and GND (pin 9) of the J1 header the ATmega1284P * enters light sensor demo mode. The light sensor is then used to adjust the * light intensity of the four leds (LED0:3). Normal demo mode will be resumed * as soon as this short is removed. * \subsection demo_mode_flowchart Demo mode flowchart * \image html demo_mode_flowchart.JPG * * * \subsection terminal_mode Terminal mode * This mode uses USART1 of the ATmega1284P to control the application. * Start hyperterminal (or the terminal program of choice) and connect to the * COM port where the XPLAINED Virtual Com Port is connected. * Select baud rate: 57k6, data bits: 8, parity: none, stop bits: 1 and * flow control: none. * * To start this mode push and hold SW1 while pressing the reset button on the * MEGA-1284P Xplained board. Supported commands and a description will * then be printed. * \subsection terminal_mode_flowchart Terminal mode flowchart * \image html terminal_mode_flowchart.JPG * * @{ */ /* * Support and FAQ: visit Atmel Support */ #include "avr_compiler.h" #include "usart.h" #include "init.h" #include "touch_api.h" #define ADC_NUM_OVERSAMPLING 16 #define ASCII_BACKSPACE 8 #define ASCII_CR 13 #define ASCII_SPACE 32 #define MAX_CMD_BUFFER_LEN 32 #define CMD_PROMPT "\r\nMEGA-1284P Xplained>" #define FLASHCOUNT 100 #define IDLE 0x01 //!< Idle SMCR setting #define POWER_DOWN 0x05 //!< Power-Down SMCR setting #define POWER_SAVE 0x07 //!< Power-Save SMCR setting #define STANDBY 0x0D //!< Standby SMCR setting #define EXTENDED_STANDBY 0x0F //!< Extended standby SMCR setting #define NUM_COMMANDS 12 // Forward declarations of command functions static void print_help (void); static void flash_leds_cmd (void); static void read_ntc (void); static void read_light_sensor (void); static void light_sensor_demo (void); static void crystal_start_cmd (void); static void crystal_stop_cmd (void); static void idle_mode_cmd (void); static void power_save_cmd (void); static void power_down_cmd (void); static void standby_cmd (void); static void ext_standby_cmd (void); //! Struct to hold all available commands, their help text and function to call struct { char cmd[20]; // Command string char help[70]; // Help text void (* func)(void); // Function to call when command is entered } commands[NUM_COMMANDS] = { { "help", "Print this help", print_help }, { "flash leds", "Toggles leds connected to PORTB0:3", flash_leds_cmd }, { "read ntc", "Returns NTC ADC code (ADC7)", read_ntc }, { "read light sensor", "Returns Light Sensor ADC code (ADC6)", read_light_sensor }, { "light sensor demo", "LED3:0 are dimmed according to the light sensor value", light_sensor_demo }, { "start 32khz crystal", "Starts the 32.768kHz crystal", crystal_start_cmd }, { "stop 32khz crystal", "Stops the 32.768kHz crystal", crystal_stop_cmd }, { "idle", "MCU in idle mode. Wake up by pressing SW0", idle_mode_cmd }, { "power-save", "MCU in Power-Save mode. Wake up by pressing SW0", power_save_cmd }, { "power-down", "MCU in Power-Down mode. Wake up by pressing SW0", power_down_cmd }, { "standby", "MCU in Standby mode. Wake up by pressing SW0", standby_cmd }, { "extended standby", "MCU in Extended Standby mode. Wake up by pressing SW0", ext_standby_cmd }, }; //! Global variable used to identify if demo mode is enabled static volatile bool light_sensor_demo_mode = false; //! Macro used for touch key detection #define QT_KEY_DETECT() \ (qt_measure_data.qt_touch_status.sensor_states[0] & 0x01) //! Number of ports using touch #define NUMBER_OF_PORTS 1 //! Touch acquisition timer period in msec. uint16_t qt_measurement_period_msec = 25; //! Flag set by timer1 overflow ISR when it's time to measure touch static volatile bool time_to_measure_touch = false; //! Current time, set by timer1 overflow ISR static volatile uint16_t current_time_ms_touch = 0; #if defined( __GNUC__ ) /** Make sure printf knows where to print. The macro fdev_setup_stream() * is used to prepare a user-supplied FILE buffer for operation with stdio. */ FILE usart1_str = FDEV_SETUP_STREAM((int(*)(char, FILE *))usart1_putchar, NULL, _FDEV_SETUP_WRITE); #endif //! ADC sources enum enum adc_sources { FILTER_OUTPUT = 0x05, //!< RC filter on ADC Channel 5, PA5 LIGHT_SENSOR = 0x06, //!< Light Sensor on ADC Channel 6, PA6 NTC = 0x07 //!< NTC sensor on ADC Channel 7, PA7 }; /** * \brief PCINT8,9,10 ISR used for wake-up from sleep only */ ISR(PCINT1_vect) { return; } /** * \brief TIMER1 overflow ISR used to dim LEDs in light sensor demo mode. * * LEDs are turned off at overflow ISR and turned on in compare match B ISR. * The compare value is adjusted according to the light sensor readings. * Brighter light will result in lower light sensor reading (ADC code) * which results in shorter time to compare match B interrupt. This means * that LEDs will be on longer than off at bright light and vice versa * at dark light. */ ISR(TIMER1_OVF_vect) { // Turn off LEDs PORTB |= (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0); // PORTB0 set to input to enable sensing on SW0 DDRB &= ~(1 << DDB0); //! \note Wait one cycle to be sure PINB0 value has stabilized. asm("nop"); // Stop demo mode if SW0 is pushed if (!(PINB & (1 << PINB0))) { light_sensor_demo_mode = false; } } /** * \brief TIMER1 compare B ISR used to dim LEDS in light sensor demo mode. * * LEDs are turned off at overflow ISR and turned on in compare match B ISR. * The compare value is adjusted according to the light sensor readings. * Brighter light will result in lower light sensor reading (ADC code) * which results in shorter time to compare match B interrupt. This means * that LEDs will be on longer than off at bright light and vice versa * at dark light. */ ISR(TIMER1_COMPB_vect) { // Turn on LEDs (make sure PORTB0 is set as output) DDRB |= (1 << DDB0); PORTB &= ~((1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0)); } /** * \brief TIMER1 compare A ISR used to time touch measurement. * * The TIMER1 compare A interrupt is used to time the touch acquisition. * The period of the timer is set by qt_measurement_period_msec. */ ISR(TIMER1_COMPA_vect) { // Set flag, it's time to measure touch time_to_measure_touch = true; // Update the current time current_time_ms_touch += qt_measurement_period_msec; } /** * \brief TIMER2 overflow ISR used to indicate 32kHz crystal running. * * All LEDs (LED0:3) are toggled to indicate that the 32kHz crystal is running. */ ISR(TIMER2_OVF_vect) { // Toggle LEDs PINB |= (1 << PINB3) | (1 << PINB2) | (1 << PINB1) | (1 << PINB0); } /** * \brief Function to flash leds flashcount amount of times. * * \param flashcount Number of times to flash LEDs */ static void flash_leds(uint8_t flashcount) { uint8_t i; for (i = 0; i < flashcount; i++) { // toggle LEDs PINB |= (1 << PINB3) | (1 << PINB2) | (1 << PINB1) | (1 << PINB0); // wait a while delay_us(20000); } // make sure LEDs are off before we leave PORTB |= (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0); } /** * \brief Function to start ADC conversion. * * This function will do ADC_NUM_OVERSAMPLINGx oversampling. Per default it * will perform 16x oversampling. * * \param channel ADC channel number * * \return adc_data Result from ADC reading of selected ADC channel */ static uint16_t read_adc(enum adc_sources source) { uint16_t adc_data = 0; // Clear old source and setup new source to sample from ADMUX &= 0xE0; ADMUX |= source; for (int i = 0 ; i < ADC_NUM_OVERSAMPLING ; i++) { //Start single conversion ADCSRA |= (1< 0) { usart1_putchar('\n'); cmd_buffer[cmd_buf_ptr] = '\0'; process_command(cmd_buffer); cmd_buf_ptr = 0; } printf(CMD_PROMPT); break; case ASCII_BACKSPACE: if (cmd_buf_ptr == 0) { break; } printf("\b \b"); cmd_buf_ptr--; break; default: if (cmd_buf_ptr >= MAX_CMD_BUFFER_LEN || data < ASCII_SPACE ) { // Break if command string is too long/ignore non-printable characters break; } cmd_buffer[cmd_buf_ptr++] = data; usart1_putchar(data); break; } } } /** brief Example code that demonstrates the some of the basic features * of the MEGA-1284P Xplained kit. * * This example code shows some of the basic features of the * MEGA-1284P Xplained kit. This includes sleep modes, reading the light sensor * and the ntc sensor. * * Please refer to the \ref application_description "detailed description" * for more information. */ int main(void) { #if defined( __GNUC__ ) /* Setup stdout to point to the correct usart (USART1). This is needed to * use the fdev_setup_stream() macro in GCC. */ stdout = &usart1_str; #endif // Make sure to use lowest possible power consumption power_reduction_enable(); // Enter terminal mode if SW1 is pressed if (!(PINB & (1 << PORTB1))) { execute_terminal_mode(); } else { execute_demo_mode(); } } //! @}