/* * Author - Mike Blandford * * Based on er9x by Erez Raviv * * Based on th9x -> http://code.google.com/p/th9x/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include #include #ifdef PCBSKY #include "radio.h" #include "drivers.h" #endif #ifdef PCBTARANIS #include "radio.h" #include "hal.h" #include "stm32f2xx.h" #include "stm32f2xx_gpio.h" #include "stm32f2xx_rcc.h" #endif #include "drivers.h" #include "logicio.h" #ifdef EVT_KEY_MASK #undef EVT_KEY_MASK #endif #define EVT_KEY_MASK 0x0f void b_putEvent( register uint8_t evt) ; void per10ms( void ) ; uint8_t getEvent( void ) ; void pauseEvents(uint8_t event) ; void killEvents(uint8_t event) ; uint8_t s_evt; void b_putEvent( uint8_t evt) { s_evt = evt; } uint8_t getEvent() { register uint8_t evt = s_evt; s_evt=0; return evt; } Key keys[NUM_KEYS] ; void Key::input(bool val, EnumKeys enuk) { // uint8_t old=m_vals; m_vals <<= 1; if(val) m_vals |= 1; //portbit einschieben m_cnt++; if(m_state && m_vals==0){ //gerade eben sprung auf 0 if(m_state!=KSTATE_KILLED) { b_putEvent(EVT_KEY_BREAK(enuk)); } m_cnt = 0; m_state = KSTATE_OFF; } switch(m_state){ case KSTATE_OFF: if(m_vals==FFVAL){ //gerade eben sprung auf ff m_state = KSTATE_START; m_cnt = 0; } break; //fallthrough case KSTATE_START: b_putEvent(EVT_KEY_FIRST(enuk)); #ifdef KSTATE_RPTDELAY m_state = KSTATE_RPTDELAY; #else m_state = 16; #endif m_cnt = 0; break; #ifdef KSTATE_RPTDELAY case KSTATE_RPTDELAY: // gruvin: longer delay before first key repeat if(m_cnt == 32) b_putEvent(EVT_KEY_LONG(enuk)); // need to catch this inside RPTDELAY time if (m_cnt == 40) { m_state = 16; m_cnt = 0; } break; #endif case 16: #ifndef KSTATE_RPTDELAY if(m_cnt == 32) b_putEvent(EVT_KEY_LONG(enuk)); //fallthrough #endif case 8: case 4: case 2: if(m_cnt >= 48) { //3 6 12 24 48 pulses in every 480ms m_state >>= 1; m_cnt = 0; } //fallthrough case 1: if( (m_cnt & (m_state-1)) == 0) b_putEvent(EVT_KEY_REPT(enuk)); break; case KSTATE_PAUSE: //pause if(m_cnt >= 64) { m_state = 8; m_cnt = 0; } break; case KSTATE_KILLED: //killed break; } } void b_pauseEvents(uint8_t event) { event=event & EVT_KEY_MASK; if(event < (int)DIM(keys)) keys[event].pauseEvents(); } void killEvents(uint8_t event) { event=event & EVT_KEY_MASK; if(event < (int)DIM(keys)) keys[event].killEvents(); } void per10ms() { register uint32_t i ; uint8_t enuk = KEY_MENU; uint8_t in = ~read_keys() ; // Bits 3-6 are down, up, right and left // Try to only allow one at a #ifdef REVX static uint8_t current ; uint8_t dir_keys ; uint8_t lcurrent ; dir_keys = in & 0x78 ; // Mask to direction keys if ( ( lcurrent = current ) ) { // Something already pressed if ( ( lcurrent & dir_keys ) == 0 ) { lcurrent = 0 ; // No longer pressed } else { in &= lcurrent | 0x06 ; // current or MENU or EXIT allowed } } if ( lcurrent == 0 ) { // look for a key if ( dir_keys & 0x20 ) // right { lcurrent = 0x60 ; // Allow L and R for 9X } else if ( dir_keys & 0x40 ) // left { lcurrent = 0x60 ; // Allow L and R for 9X } else if ( dir_keys & 0x08 ) // down { lcurrent = 0x08 ; } else if ( dir_keys & 0x10 ) // up { lcurrent = 0x10 ; } in &= lcurrent | 0x06 ; // current or MENU or EXIT allowed } current = lcurrent ; #endif for( i=1; i<7; i++) { uint8_t value = in & (1<