diff --git a/Device/Port.cpp b/Device/Port.cpp index a6c0480e..58c6a7f3 100644 --- a/Device/Port.cpp +++ b/Device/Port.cpp @@ -13,10 +13,10 @@ static bool Port_Reserve(Pin pin, bool flag); #ifdef REGION_Port Port::Port() { - _Pin = P0; - Opened = false; - Index = 0; - State = nullptr; + _Pin = P0; + Opened = false; + Index = 0; + State = nullptr; } #ifndef TINY @@ -28,15 +28,15 @@ Port::~Port() String& Port::ToStr(String& str) const { - str += 'P'; - if(_Pin == P0) + str += 'P'; + if (_Pin == P0) { - str += '0'; + str += '0'; } else { - str += (char)('A' + (_Pin >> 4)); - str += (byte)(_Pin & 0x0F); + str += (char)('A' + (_Pin >> 4)); + str += (byte)(_Pin & 0x0F); } return str; } @@ -45,35 +45,35 @@ String& Port::ToStr(String& str) const Port& Port::Set(Pin pin) { // 如果引脚不变,则不做处理 - if(pin == _Pin) return *this; + if (pin == _Pin) return *this; #ifndef TINY // 释放已有引脚的保护 - if(_Pin != P0) Close(); + if (_Pin != P0) Close(); #endif - _Pin = pin; + _Pin = pin; return *this; } bool Port::Empty() const { - if(_Pin != P0) return false; + if (_Pin != P0) return false; return true; } void Port::Clear() { - _Pin = P0; + _Pin = P0; } // 确定配置,确认用对象内部的参数进行初始化 bool Port::Open() { - if(_Pin == P0) return false; - if(Opened) return true; + if (_Pin == P0) return false; + if (Opened) return true; TS("Port::Open"); @@ -94,8 +94,8 @@ bool Port::Open() void Port::Close() { - if(!Opened) return; - if(_Pin == P0) return; + if (!Opened) return; + if (_Pin == P0) return; OnClose(); @@ -123,36 +123,37 @@ WEAK void Port::AFConfig(GPIO_AF GPIO_AF) const {} #if DEBUG // 引脚保留位,记录每个引脚是否已经被保留,禁止别的模块使用 // !!!注意,不能全零,否则可能会被当作zeroinit而不是copy,导致得不到初始化 -static ushort Reserved[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF}; +static ushort Reserved[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF }; // 保护引脚,别的功能要使用时将会报错。返回是否保护成功 bool Port_Reserve(Pin pin, bool flag) { debug_printf("::"); - int port = pin >> 4, bit = 1 << (pin & 0x0F); - if (flag) { - if (Reserved[port] & bit) { + int port = pin >> 4, bit = 1 << (pin & 0x0F); + if (flag) { + if (Reserved[port] & bit) { // 增加针脚已经被保护的提示,很多地方调用ReservePin而不写日志,得到False后直接抛异常 debug_printf("P%c%d 已被打开", _PIN_NAME(pin)); return false; // already reserved } - Reserved[port] |= bit; + Reserved[port] |= bit; debug_printf("打开 P%c%d", _PIN_NAME(pin)); - } else { - Reserved[port] &= ~bit; + } + else { + Reserved[port] &= ~bit; debug_printf("关闭 P%c%d", _PIN_NAME(pin)); } - return true; + return true; } /*// 引脚是否被保护 bool Port::IsBusy(Pin pin) { - int port = pin >> 4, sh = pin & 0x0F; - return (Reserved[port] >> sh) & 1; + int port = pin >> 4, sh = pin & 0x0F; + return (Reserved[port] >> sh) & 1; }*/ #endif @@ -166,11 +167,11 @@ OutputPort::OutputPort() : Port() { } OutputPort::OutputPort(Pin pin) : OutputPort(pin, 2) { } OutputPort::OutputPort(Pin pin, byte invert, bool openDrain, byte speed) : Port() { - OpenDrain = openDrain; - Speed = speed; - Invert = invert; + OpenDrain = openDrain; + Speed = speed; + Invert = invert; - if(pin != P0) + if (pin != P0) { Set(pin); Open(); @@ -181,7 +182,7 @@ OutputPort& OutputPort::Init(Pin pin, bool invert) { Port::Set(pin); - Invert = invert; + Invert = invert; return *this; } @@ -192,27 +193,27 @@ void OutputPort::OnOpen() #if DEBUG debug_printf(" %dM", Speed); - if(OpenDrain) + if (OpenDrain) debug_printf(" 开漏"); else debug_printf(" 推挽"); - bool fg = false; + bool fg = false; #endif // 根据倒置情况来获取初始状态,自动判断是否倒置 bool rs = Port::Read(); - if(Invert > 1) + if (Invert > 1) { - Invert = rs; + Invert = rs; #if DEBUG - fg = true; + fg = true; #endif } #if DEBUG - if(Invert) + if (Invert) { - if(fg) + if (fg) debug_printf(" 自动倒置"); else debug_printf(" 倒置"); @@ -230,41 +231,41 @@ void OutputPort::OnOpen() WEAK bool OutputPort::ReadInput() const { - if(Empty()) return false; + if (Empty()) return false; return Port::Read() ^ Invert; } void OutputPort::Up(uint ms) const { - if(Empty()) return; + if (Empty()) return; - Write(true); + Write(true); Sys.Sleep(ms); - Write(false); + Write(false); } void OutputPort::Down(uint ms) const { - if(Empty()) return; + if (Empty()) return; - Write(false); + Write(false); Sys.Sleep(ms); - Write(true); + Write(true); } void OutputPort::Blink(uint times, uint ms) const { - if(Empty()) return; + if (Empty()) return; bool flag = true; - for(int i=0; i 0 && ShakeTime > 0 && ((Int64)now - (Int64)_Last) < ShakeTime) return; - _Last = now; + if (_Last > 0 && ShakeTime > 0 && ((Int64)now - (Int64)_Last) < ShakeTime) return; + _Last = now; // 允许两个值并存 - _Value = down ? Rising : Falling; + _Value = down ? Rising : Falling; - if(down) - _Start = now; + if (down) + _Start = now; else - PressTime = now - _Start; + PressTime = now - _Start; /*if(down) { @@ -372,7 +373,7 @@ void InputPort::OnPress(bool down) if((Mode & Falling) == 0) return; }*/ - if(HardEvent || !_IRQ) + if (HardEvent || !_IRQ) Press(*this, down); else Sys.SetTask(_task, true, 0); @@ -380,19 +381,23 @@ void InputPort::OnPress(bool down) void InputPort::InputTask(void* param) { - auto port = (InputPort*)param; - byte v = port->_Value; - if(!v) return; + auto port = (InputPort*)param; + byte v = port->_Value; + if (!v) return; //v &= port->Mode; - if(v & Rising) port->Press(*port, true); - if(v & Falling) port->Press(*port, false); + if (v & Rising) port->Press(*port, true); + if (v & Falling) port->Press(*port, false); } -static void InputNoIRQTask(void* param) +void InputPort::InputNoIRQTask(void* param) { - auto port = (InputPort*)param; - port->OnPress(port->Read()); + auto port = (InputPort*)param; + auto val = port->Read(); + if (val == port->Val) return; + port->Val = val; + + port->OnPress(val); } void InputPort::OnOpen() @@ -400,19 +405,19 @@ void InputPort::OnOpen() TS("InputPort::OnOpen"); // 如果不是硬件事件,则默认使用20ms抖动 - if(!HardEvent && ShakeTime == 0) ShakeTime = 20; + if (!HardEvent && ShakeTime == 0) ShakeTime = 20; #if DEBUG debug_printf(" 抖动=%dms", ShakeTime); - if(Floating) + if (Floating) debug_printf(" 浮空"); - else if(Pull == UP) + else if (Pull == UP) debug_printf(" 上升沿"); - else if(Pull == DOWN) + else if (Pull == DOWN) debug_printf(" 下降沿"); //if(Mode & Rising) debug_printf(" 按下"); //if(Mode & Falling) debug_printf(" 弹起"); - bool fg = false; + bool fg = false; #endif Port::OnOpen(); @@ -420,18 +425,18 @@ void InputPort::OnOpen() // 根据倒置情况来获取初始状态,自动判断是否倒置 bool rs = Port::Read(); - if(Invert > 1) + if (Invert > 1) { - Invert = rs; + Invert = rs; #if DEBUG - fg = true; + fg = true; #endif } #if DEBUG - if(Invert) + if (Invert) { - if(fg) + if (fg) debug_printf(" 自动倒置"); else debug_printf(" 倒置"); @@ -451,21 +456,21 @@ void InputPort::OnClose() } // 输入轮询时间间隔。默认100ms,允许外部修改 -uint InputPort_Polling = 100; +uint InputPort_Polling = 100; bool InputPort::UsePress() { assert(_Pin != P0, "输入注册必须先设置引脚"); - _IRQ = OnRegister(); + _IRQ = OnRegister(); if (!_task && !HardEvent) { // 如果硬件中断注册失败,则采用10ms定时读取 - if(_IRQ) - _task = Sys.AddTask(InputTask, this, -1, -1, "输入事件"); + if (_IRQ) + _task = Sys.AddTask(InputTask, this, -1, -1, "输入事件"); else - _task = Sys.AddTask(InputNoIRQTask, this, InputPort_Polling, InputPort_Polling, "输入轮询"); + _task = Sys.AddTask(InputNoIRQTask, this, InputPort_Polling, InputPort_Polling, "输入轮询"); } return true; diff --git a/Device/Port.h b/Device/Port.h index a660a59e..2e5c54dd 100644 --- a/Device/Port.h +++ b/Device/Port.h @@ -184,16 +184,19 @@ protected: private: bool _IRQ = false; - byte _Value = 0; // 当前值 + uint _task = 0; // 输入任务 UInt64 _Start = 0; // 开始按下时间 UInt64 _Last = 0; // 最后一次触发时间 static void InputTask(void* param); + static void InputNoIRQTask(void* param); private: void OpenPin(); void ClosePin(); bool OnRegister(); + byte _Value = 0; // 当前值 + bool Val = false; }; /******************************** AnalogInPort ********************************/