Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/master' into spi_bitbang
- Loading branch information
Showing
8 changed files
with
786 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# | ||
# Copyright 2008-2012 Michel Pollet <buserror@gmail.com> | ||
# Copyright 2018 Doug Szumski <d.s.szumski@gmail.com> | ||
# | ||
# This file is part of simavr. | ||
# | ||
# simavr is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# simavr 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. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with simavr. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
target=rotenc_test | ||
firm_src = ${wildcard at*${board}.c} | ||
firmware = ${firm_src:.c=.axf} | ||
simavr = ../.. | ||
|
||
IPATH = . | ||
IPATH += ${simavr}/examples/shared | ||
IPATH += ${simavr}/examples/parts | ||
IPATH += ${simavr}/include | ||
IPATH += ${simavr}/simavr/sim | ||
|
||
VPATH = . | ||
VPATH += ${simavr}/examples/shared | ||
VPATH += ${simavr}/examples/parts | ||
|
||
LDFLAGS += -lpthread | ||
|
||
include ../Makefile.opengl | ||
|
||
all: obj ${firmware} ${target} | ||
|
||
include ${simavr}/Makefile.common | ||
|
||
atmega1280_${target}.axf: atmega32_${target}.c | ||
|
||
board = ${OBJ}/${target}.elf | ||
|
||
${board} : ${OBJ}/${target}.o | ||
${board} : ${OBJ}/rotenc.o | ||
|
||
${target}: ${board} | ||
@echo $@ done | ||
|
||
clean: clean-${OBJ} | ||
rm -rf *.hex *.a *.axf ${target} *.vcd .*.swo .*.swp .*.swm .*.swn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
board_rotenc | ||
|
||
This sample code demonstrates the use of a virtual Panasonic EVEP rotary | ||
encoder. The encoder is hooked up to an LED array, and is used to scroll | ||
an LED up and down. It behaves just like in real life, except contact | ||
bounce is not modelled. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
atmega32_rotenc_test.c | ||
A simple example demonstrating a Pansonic EVEP rotary encoder | ||
scrolling an LED up and down an 8 segment LED bar. | ||
Copyright 2018 Doug Szumski <d.s.szumski@gmail.com> | ||
This file is part of simavr. | ||
simavr is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
simavr 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. | ||
You should have received a copy of the GNU General Public License | ||
along with simavr. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <avr/io.h> | ||
#include <avr/interrupt.h> | ||
#include <avr/sleep.h> | ||
#include <stdio.h> | ||
|
||
#include "avr_mcu_section.h" | ||
AVR_MCU(F_CPU, "atmega32"); | ||
|
||
typedef enum { | ||
CLOCKWISE, | ||
COUNTERCLOCKWISE | ||
} led_scroll_dir_t; | ||
|
||
/* Initialise the inputs for signal A and signal B from the rotary encoder. | ||
* They are hooked up to INTO on PD2 and GPIO pin PA0. Pull-ups are on the | ||
* PCB. */ | ||
void | ||
rotary_spin_int_init(void) | ||
{ | ||
// Set INT0 and GPIO pin as inputs | ||
DDRD &= ~(1 << PD2) & ~(1 << PA0); | ||
// Any logical change on INT0 generates an interrupt (see DS p.67) | ||
MCUCR |= (1 << ISC00); | ||
MCUCR &= ~(1 << ISC01); | ||
// Enable interrupt pin PD2 | ||
GICR |= (1 << INT0); | ||
} | ||
|
||
/* Initialise inputs for signal C from the rotary encoder (button). This | ||
* is hooked up to INT2 on PB2. A pull-up is on the PCB. */ | ||
void | ||
rotary_button_int_init(void) | ||
{ | ||
DDRB &= ~(1 << PB2); | ||
// Falling edge trigger (pin is pulled up) (see DS p.67) | ||
MCUCSR &= ~(1 << ISC2); | ||
// Enable interrupt pin PB2 | ||
GICR |= (1 << INT2); | ||
} | ||
|
||
/* Configure 8 segment virtual 'LED bar' on port C */ | ||
void | ||
led_bar_init(void) | ||
{ | ||
DDRC = 0xFF; // All outputs | ||
PORTC = 0b00010000; // Start with a light on in the middle | ||
} | ||
|
||
void | ||
led_bar_scroll(led_scroll_dir_t dir) | ||
{ | ||
switch (dir) { | ||
case CLOCKWISE: | ||
if (PORTC < 0b10000000) PORTC <<= 1; | ||
break; | ||
case COUNTERCLOCKWISE: | ||
if (PORTC > 0b00000001) PORTC >>= 1; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
int | ||
main() | ||
{ | ||
// Disable interrupts whilst configuring them to avoid false triggers | ||
cli(); | ||
rotary_spin_int_init(); | ||
rotary_button_int_init(); | ||
sei(); | ||
|
||
led_bar_init(); | ||
|
||
while (1) { | ||
// Wait for some input | ||
} | ||
|
||
cli(); | ||
sleep_mode(); | ||
} | ||
|
||
ISR(INT0_vect) | ||
{ | ||
// The Panasonic EVEP rotary encoder this is written for moves two | ||
// phases for every 'click' it emits. The interrupt is configured | ||
// to fire on every edge change of B, which is once per 'click'. | ||
// Moving forwards in phase, after B has changed state we poll A. | ||
// We get the sequence (A=0,B=1), (A=1,B=0). Moving backwards in | ||
// phase, after B has changed state we get (A=1,B=1), (A=0,B=0). | ||
// | ||
// +-------+---+---+ | ||
// | Phase | A | B | | ||
// +-------+---+---+ | ||
// | 0 | 0 | 0 | | ||
// | 1 | 0 | 1 | | ||
// | 2 | 1 | 1 | | ||
// | 3 | 1 | 0 | | ||
// +-------+---+---+ | ||
// | ||
// The twist direction is then obtained by taking the logical | ||
// XOR of outputs A and B after the interrupt has fired. Of | ||
// course with a 'real life' part you might be better off | ||
// using a state machine, or some extra hardware to filter out | ||
// contact bounces which aren't modelled in the virtual part. | ||
uint8_t ccw_twist = ((PIND & (1 << PD2)) >> 2) ^ (PINA & (1 << PA0)); | ||
|
||
// Scroll the LED bar | ||
if (ccw_twist) { | ||
led_bar_scroll(COUNTERCLOCKWISE); | ||
} else { | ||
led_bar_scroll(CLOCKWISE); | ||
} | ||
} | ||
|
||
ISR(INT2_vect) | ||
{ | ||
// Fires when rotary encoder button was pressed and resets | ||
// the LED bar to the starting position | ||
PORTC = 0b00010000; | ||
} |
Oops, something went wrong.