inital commit
This commit is contained in:
		
						commit
						51a5e6fc28
					
				
					 10 changed files with 489 additions and 0 deletions
				
			
		
							
								
								
									
										54
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| # Project name | ||||
| project(asteleMotor) | ||||
| 
 | ||||
| # CMake version | ||||
| cmake_minimum_required(VERSION 2.6) | ||||
| 
 | ||||
| # Options | ||||
| set(MCU "attiny2313" CACHE STRING "Processor Type") | ||||
| set(CPU_SPEED "4000000" CACHE STRING "Speed of the CPU") | ||||
| set(PORT "/dev/ttyUSB0" CACHE STRING "USB Port") | ||||
| set(PORT_SPEED "57600" CACHE STRING "Serial Port Speed") | ||||
| set(PROGRAMMER "usbasp" CACHE STRING "Programmer Type") | ||||
| set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags") | ||||
| 
 | ||||
| # Set own source files | ||||
| set(SRC_FILES  main.cpp writepin.cpp comperator.cpp stepper.cpp) | ||||
| 
 | ||||
| # Compiler suite specification | ||||
| set(CMAKE_C_COMPILER /usr/bin/avr-gcc) | ||||
| set(CMAKE_CXX_COMPILER /usr/bin/avr-g++) | ||||
| set(CMAKE_OBJCOPY /usr/bin/avr-objcopy) | ||||
| set(CMAKE_OBJDUMP /usr/bin/avr-objdump) | ||||
| set(CMAKE_RANLIB /usr/bin/avr-ranlib) | ||||
| set(CMAKE_LINKER /usr/bin/avr-ld) | ||||
| 
 | ||||
| # Compiler flags | ||||
| add_definitions(-mmcu=${MCU} -DF_CPU=${CPU_SPEED}) | ||||
| add_definitions(-c -g -Os -flto -Wall -std=c++17 ) | ||||
| add_definitions(-fno-exceptions -ffunction-sections -fno-rtti -fdata-sections) | ||||
| 
 | ||||
| # Linker flags | ||||
| set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")   # remove -rdynamic for C | ||||
| set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") # remove -rdynamic for CXX | ||||
| set(CMAKE_EXE_LINKER_FLAGS "-s -Os -Wl,--gc-sections -mmcu=${MCU}") | ||||
| 
 | ||||
| add_executable(${PROJECT_NAME} ${ARDUINO_CORE_SRC} ${SRC_FILES}) | ||||
| 
 | ||||
| find_program(AR_AVRDUDE NAMES avrdude PATHS /usr/bin NO_DEFAULT_PATH) | ||||
| find_program(AR_AVRSIZE NAMES avr-size PATHS /usr/bin NO_DEFAULT_PATH) | ||||
| 
 | ||||
| add_custom_target(download  | ||||
| 	COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${PROJECT_NAME} ${PROJECT_NAME}.hex | ||||
| 	COMMAND ${AR_AVRSIZE} -C ${PROJECT_NAME} | ||||
| 	COMMAND ${AR_AVRDUDE} -v -p ${MCU} -c ${PROGRAMMER} -D -U flash:w:${PROJECT_NAME}.hex | ||||
| 	DEPENDS ${PROJECT_NAME} | ||||
| 	) | ||||
| 	 | ||||
| 	message(STATUS "${CPU_SPEED}") | ||||
| 	 | ||||
| add_custom_target(export  | ||||
| COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${PROJECT_NAME} ${PROJECT_NAME}.hex | ||||
| COMMAND ${AR_AVRSIZE} -C ${PROJECT_NAME} | ||||
| DEPENDS ${PROJECT_NAME} | ||||
| ) | ||||
							
								
								
									
										44
									
								
								buttons.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								buttons.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <avr/io.h> | ||||
| #include "writepin.h" | ||||
| 
 | ||||
| class Buttons  | ||||
| { | ||||
| 	public: | ||||
| 		 | ||||
| 	static constexpr uint8_t PRESSED = 0; | ||||
| 	static constexpr uint8_t LONG_PRESSED = 1; | ||||
| 	static constexpr uint8_t RELEASED     = 2; | ||||
| 		 | ||||
| 	private: | ||||
| 	volatile uint8_t * const pinReg = &PIND; | ||||
| 	static constexpr uint8_t button[] = { PD5, PD6 }; | ||||
| 	static constexpr uint8_t buttonsAmount = sizeof(button); | ||||
| 	uint8_t buttonCount[buttonsAmount] = {}; | ||||
| 	 | ||||
| 	void* _userData; | ||||
| 	void (*_eventHandler)(uint8_t index, uint8_t type, void* data); | ||||
| 	 | ||||
| 	public: | ||||
| 	Buttons(void (*eventHandler)(uint8_t index, uint8_t type, void* data), void* userData = nullptr): _userData(userData), _eventHandler(eventHandler){} | ||||
| 	void tick(); | ||||
| }; | ||||
| 
 | ||||
| void Buttons::tick() | ||||
| { | ||||
| 	for(uint8_t i = 0; i < buttonsAmount; ++i) | ||||
| 	{ | ||||
| 		if(readPin(pinReg, button[i]) == true) | ||||
| 		{ | ||||
| 			if(buttonCount[i] > 2) _eventHandler(i, RELEASED, _userData); | ||||
| 			buttonCount[i] = 0; | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			if(buttonCount[i] == 3)   _eventHandler(i, PRESSED, _userData); | ||||
| 			else if(buttonCount[i] == 100) _eventHandler(i, LONG_PRESSED, _userData); | ||||
| 			++buttonCount[i]; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										22
									
								
								comperator.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								comperator.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #include "comperator.h" | ||||
| 
 | ||||
| Comperator::Comperator() | ||||
| { | ||||
|     if constexpr(INTERNAL_REFERANCE)  ACSR = 0b01000001; | ||||
|     else ACSR = 0b00000011; | ||||
| } | ||||
| 
 | ||||
| void Comperator::on() | ||||
| { | ||||
|     ACSR &= 0b01111111; | ||||
| } | ||||
| 
 | ||||
| void Comperator::off() | ||||
| { | ||||
|     ACSR |= 0b10000000; | ||||
| } | ||||
| 
 | ||||
| bool Comperator::compare() | ||||
| { | ||||
|     return ACSR & 0b00100000; | ||||
| } | ||||
							
								
								
									
										13
									
								
								comperator.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								comperator.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| #pragma once | ||||
| #include <avr/io.h> | ||||
| 
 | ||||
| class Comperator | ||||
| { | ||||
|     static constexpr bool INTERNAL_REFERANCE = true; | ||||
| public: | ||||
|     Comperator(); | ||||
|      | ||||
|     static void on(); | ||||
|     static void off(); | ||||
|     static bool compare(); | ||||
| }; | ||||
							
								
								
									
										51
									
								
								eeprom.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								eeprom.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| void EEPROM_write_char(uint16_t address, unsigned char data) | ||||
| { | ||||
|     //Wait for completion of previous write
 | ||||
|     while(EECR & (1<<EEPE)); | ||||
|     //Set up address and Data Registers
 | ||||
|     EEAR = address; | ||||
|     EEDR = data; | ||||
|     //Write logical one to EEMPE
 | ||||
|     EECR |= (1<<EEMPE); | ||||
|     //Start eeprom write by setting EEPE
 | ||||
|     EECR |= (1<<EEPE); | ||||
| } | ||||
| 
 | ||||
| unsigned char EEPROM_read_char(uint16_t uiAddress) | ||||
| { | ||||
|     // Wait for completion of previous write
 | ||||
|     while(EECR & (1<<EEPE)); | ||||
|     //Set up address register
 | ||||
|     EEAR = uiAddress; | ||||
|     //Start eeprom read by writing EERE
 | ||||
|     EECR |= (1<<EERE); | ||||
|     //Return data from Data Register
 | ||||
|     return EEDR; | ||||
| } | ||||
| 
 | ||||
| void EEPROM_write_string(uint16_t address, char* buffer, uint16_t length) | ||||
| { | ||||
|     for(uint16_t i = 0; i < length; i++) EEPROM_write_char( address+i, buffer[i] ); | ||||
| } | ||||
| 
 | ||||
| void EEPROM_read_string(uint16_t address, char* buffer, uint16_t length) | ||||
| { | ||||
|     for(uint16_t i = 0; i < length; i++) buffer[i] = EEPROM_read_char( address+i); | ||||
| } | ||||
| 
 | ||||
| template <class T> void EEPROM_write_class(uint16_t address, T& in) | ||||
| { | ||||
|     EEPROM_write_string( address, reinterpret_cast<char*>(&in), sizeof(in)); | ||||
| } | ||||
| 
 | ||||
| template <class T> T EEPROM_read_class(uint16_t address) | ||||
| { | ||||
|     char data[sizeof(T)]; | ||||
|     EEPROM_read_string( address, data, sizeof(T) ); | ||||
|     return *reinterpret_cast<T*>(data); | ||||
| } | ||||
| 
 | ||||
| template <class T> void EEPROM_read_class(uint16_t address, T* in) | ||||
| { | ||||
|     EEPROM_read_string( address, reinterpret_cast<char*>(in), sizeof(T) ); | ||||
| } | ||||
							
								
								
									
										137
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| #include <stdint.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/sleep.h> | ||||
| #include "stepper.h" | ||||
| #include "writepin.h" | ||||
| #include "comperator.h" | ||||
| #include "buttons.h" | ||||
| #include "eeprom.h" | ||||
| 
 | ||||
| #define LED_1_PIN PB3 | ||||
| #define LED_2_PIN PB4 | ||||
| 
 | ||||
| #define BUTTON_1_PIN PD5 | ||||
| #define BUTTON_2_PIN PD6 | ||||
| 
 | ||||
| bool setup = false; | ||||
| static bool buttonLongpressed[2]; | ||||
| uint8_t lockedSpeed = 180; | ||||
| 
 | ||||
| void debugBlink(bool fast = true) | ||||
| { | ||||
| 	_delay_ms(100); | ||||
| 	if(!fast) _delay_ms(200);  | ||||
| 	PORTB |= 1 << LED_1_PIN; | ||||
| 	_delay_ms(100); | ||||
| 	if(!fast) _delay_ms(200);  | ||||
| 	PORTB &= ~(1 << LED_1_PIN); | ||||
| } | ||||
| 
 | ||||
| void buttonHandler(uint8_t index, uint8_t type, void* data) | ||||
| { | ||||
| 	Stepper* stepper = reinterpret_cast<Stepper*>(data); | ||||
| 	if(setup == false) | ||||
| 	{ | ||||
| 		if(type == Buttons::PRESSED) | ||||
| 		{ | ||||
| 			if(index == 0)  | ||||
| 			{ | ||||
| 				stepper->setSpeed(230); | ||||
| 				stepper->setEndlesMove(true, true); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				stepper->setSpeed(230); | ||||
| 				stepper->setEndlesMove(true, false); | ||||
| 			} | ||||
| 		} | ||||
| 		else if(type == Buttons::RELEASED) | ||||
| 		{ | ||||
| 			stepper->setSpeed(lockedSpeed); | ||||
| 			stepper->setEndlesMove(true, true); | ||||
| 			buttonLongpressed[0] = false; | ||||
| 			buttonLongpressed[1] = false; | ||||
| 		} | ||||
| 		else if(type == Buttons::LONG_PRESSED) | ||||
| 		{ | ||||
| 			buttonLongpressed[index] = true; | ||||
| 			if(buttonLongpressed[0] && buttonLongpressed[1]) | ||||
| 			{ | ||||
| 				writePin(&PORTB, LED_2_PIN, true); | ||||
| 				writePin(&PORTB, LED_1_PIN, false); | ||||
| 				setup = true; | ||||
| 				buttonLongpressed[0] = false; | ||||
| 				buttonLongpressed[1] = false; | ||||
| 				stepper->setSpeed(lockedSpeed); | ||||
| 				stepper->setEndlesMove(true, true); | ||||
| 				debugBlink(); | ||||
| 				debugBlink(); | ||||
| 				debugBlink(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if(type == Buttons::PRESSED) writePin(&PORTB, LED_1_PIN, true); | ||||
| 		if(type == Buttons::RELEASED) | ||||
| 		{ | ||||
| 			writePin(&PORTB, LED_1_PIN, false); | ||||
| 			if(index == 0) | ||||
| 			{ | ||||
| 				lockedSpeed+=5; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				lockedSpeed-=5; | ||||
| 			} | ||||
| 			EEPROM_write_char(0, lockedSpeed); | ||||
| 			stepper->setSpeed(lockedSpeed); | ||||
| 		} | ||||
| 		else if(type == Buttons::LONG_PRESSED) | ||||
| 		{ | ||||
| 			buttonLongpressed[index] = true; | ||||
| 			if(buttonLongpressed[0] && buttonLongpressed[1]) | ||||
| 			{ | ||||
| 				writePin(&PORTB, LED_2_PIN, false); | ||||
| 				writePin(&PORTB, LED_1_PIN, true); | ||||
| 				setup = false; | ||||
| 				buttonLongpressed[0] = false; | ||||
| 				buttonLongpressed[1] = false; | ||||
| 				stepper->setSpeed(lockedSpeed); | ||||
| 				stepper->setEndlesMove(true, true); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
| 	DDRB  = 1 << LED_1_PIN | 1 << LED_2_PIN; | ||||
| 	DDRD  = 1 << PD0 | 1 << PD1 | 1 << PD2 | 1 << PD3; | ||||
| 	PORTD = 1 << BUTTON_1_PIN | 1 << BUTTON_2_PIN; | ||||
| 	 | ||||
| 	if(EEPROM_read_char(0) != 0) lockedSpeed = EEPROM_read_char(0); | ||||
| 	 | ||||
| 	Stepper stepper(&PORTD, PD0, PD1, PD2, PD3); | ||||
| 	 | ||||
| 	debugBlink(false); | ||||
| 	debugBlink(false); | ||||
| 	 | ||||
| 	writePin(&PORTB, LED_1_PIN, true); | ||||
| 	stepper.setSpeed(180); | ||||
| 	stepper.setEndlesMove(true); | ||||
| 	 | ||||
| 	Buttons buttons(&buttonHandler, reinterpret_cast<void*>(&stepper)); | ||||
| 	 | ||||
| 	uint8_t timer = 0; | ||||
| 	 | ||||
| 	while(true) | ||||
| 	{ | ||||
| 		if(++timer == 0)buttons.tick(); | ||||
| 		stepper.tick(); | ||||
| 		_delay_us(50); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										92
									
								
								stepper.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								stepper.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | |||
| 
 | ||||
| #include "stepper.h" | ||||
| #include "writepin.h" | ||||
| 
 | ||||
| void Stepper::tick() | ||||
| { | ||||
| 	if(++_tickCounter > UINT8_MAX - (_speed>>8) ) | ||||
| 	{ | ||||
| 		if(_targetStep != _currentStep) | ||||
| 		{ | ||||
| 			step(_targetStep > _currentStep); | ||||
| 		} | ||||
| 		else if(endlessMove) step(endlessDriection); | ||||
| 		_tickCounter = 0; | ||||
| 	} | ||||
| 	if(_speed>>8 < _targetSpeed) _speed = _speed + acceleration; | ||||
| 	else if(_speed>>8 > _targetSpeed)_speed = _speed - acceleration;; | ||||
| } | ||||
| 
 | ||||
| void Stepper::moveTo(const int32_t step) | ||||
| { | ||||
| 	_targetStep = step; | ||||
| } | ||||
| 
 | ||||
| void Stepper::moveRelative(const int16_t dist) | ||||
| { | ||||
|     moveTo(_targetStep + dist); | ||||
| } | ||||
| 
 | ||||
| void Stepper::setSpeed(const uint8_t speed) | ||||
| { | ||||
|     _targetSpeed = speed; | ||||
| 	if(_targetSpeed < speedFloor) _targetSpeed = speedFloor; | ||||
| } | ||||
| 
 | ||||
| void Stepper::setEndlesMove(bool endless, bool direction) | ||||
| { | ||||
| 	endlessMove = endless; | ||||
| 	if(direction != endlessDriection) | ||||
| 	{ | ||||
| 		_speed = speedFloor; | ||||
| 		endlessDriection = direction; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| uint32_t Stepper::isAt() | ||||
| { | ||||
|     return _currentStep; | ||||
| } | ||||
|      | ||||
| bool Stepper::isStoped() | ||||
| { | ||||
|     return _currentStep == _targetStep; | ||||
| } | ||||
| 
 | ||||
| void Stepper::step(bool direction) | ||||
| { | ||||
| 	switch(_currentStep & 0x03) | ||||
| 	{ | ||||
| 		case 0: | ||||
| 		writePin(_port, _pinA, true); | ||||
| 		writePin(_port, _pinB, false); | ||||
| 		writePin(_port, _pinC, false); | ||||
| 		writePin(_port, _pinD, true); | ||||
| 		break; | ||||
| 		case 1: | ||||
| 		writePin(_port, _pinA, true); | ||||
| 		writePin(_port, _pinB, true); | ||||
| 		writePin(_port, _pinC, false); | ||||
| 		writePin(_port, _pinD, false); | ||||
| 		break; | ||||
| 		case 2: | ||||
| 		writePin(_port, _pinA, false); | ||||
| 		writePin(_port, _pinB, true); | ||||
| 		writePin(_port, _pinC, true); | ||||
| 		writePin(_port, _pinD, false); | ||||
| 		break; | ||||
| 		case 3: | ||||
| 		writePin(_port, _pinA, false); | ||||
| 		writePin(_port, _pinB, false); | ||||
| 		writePin(_port, _pinC, true); | ||||
| 		writePin(_port, _pinD, true); | ||||
| 		break; | ||||
| 		default: | ||||
| 		writePin(_port, _pinA, false); | ||||
| 		writePin(_port, _pinB, false); | ||||
| 		writePin(_port, _pinC, false); | ||||
| 		writePin(_port, _pinD, false); | ||||
| 	} | ||||
| 	_currentStep = _currentStep + (direction ? 1 : -1); | ||||
| 	if(endlessMove) _targetStep = _currentStep; | ||||
| } | ||||
							
								
								
									
										42
									
								
								stepper.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								stepper.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| class Stepper | ||||
| { | ||||
| private: | ||||
|     volatile uint8_t * const _port; | ||||
|     const uint8_t _pinA; | ||||
|     const uint8_t _pinB; | ||||
|     const uint8_t _pinC; | ||||
| 	const uint8_t _pinD; | ||||
|      | ||||
|     static constexpr uint8_t acceleration = 5; | ||||
| 	static constexpr uint8_t speedFloor = 50; | ||||
| 	 | ||||
| 	bool endlessMove = false; | ||||
| 	bool endlessDriection = true; | ||||
|      | ||||
|     uint16_t _speed = speedFloor; | ||||
|     uint8_t _targetSpeed = 220; | ||||
| 	uint8_t _stepInterval = 0; | ||||
|      | ||||
|     uint16_t _tickCounter = 0; | ||||
|      | ||||
|     int32_t _currentStep = 0; | ||||
|     int32_t _targetStep = 0; | ||||
|      | ||||
|     void step(bool direction); | ||||
| 	 | ||||
|      | ||||
| public: | ||||
|      | ||||
|     Stepper( volatile uint8_t * const port, const uint8_t pinA, const uint8_t pinB, const uint8_t pinC, const uint8_t pinD): _port(port), _pinA(pinA), _pinB(pinB), _pinC(pinC), _pinD(pinD){} | ||||
|     void tick(); | ||||
|     void moveTo(const int32_t step); | ||||
|     void moveRelative(const int16_t dist); | ||||
|     void setSpeed(const uint8_t speed); | ||||
|     uint32_t isAt(); | ||||
|     bool isStoped(); | ||||
| 	void setEndlesMove(bool endless, bool direction = true); | ||||
| }; | ||||
							
								
								
									
										20
									
								
								writepin.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								writepin.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| #include "writepin.h" | ||||
| 
 | ||||
| void writePin(volatile unsigned char * const port, const unsigned char pin, const bool state) | ||||
| { | ||||
| 	*port = (*port & ~(1 << pin)) | (1 << pin)*state; | ||||
|     //if(!state) *port &= ~(1 << pin);
 | ||||
|     //else *port |= (1 << pin);
 | ||||
| } | ||||
| 
 | ||||
| void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ) | ||||
| { | ||||
|     writePin(reg, bit, value); | ||||
| } | ||||
| 
 | ||||
| void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ) | ||||
| { | ||||
|     writePin(portDirReg, pin, makeOutput); | ||||
| } | ||||
| 
 | ||||
| bool readPin( volatile const unsigned char * const inPort, const unsigned char pin){ return (bool) (*inPort & (1 << pin));} | ||||
							
								
								
									
										14
									
								
								writepin.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								writepin.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| #ifndef WRITEPIN_H | ||||
| #define WRITEPIN_H | ||||
| #include <avr/io.h> | ||||
| 
 | ||||
| 
 | ||||
| void  writePin(volatile unsigned char * const port, const unsigned char pin, const bool state); | ||||
| 
 | ||||
| void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ); | ||||
| 
 | ||||
| void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ); | ||||
| 
 | ||||
| bool readPin( volatile const unsigned char * const inPort, const unsigned char pin); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue