initial version
This commit is contained in:
commit
ae7bcc5136
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
build
|
62
Makefile
Normal file
62
Makefile
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
TARGET = rc5switch
|
||||||
|
TARGET_MCU = attiny24
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
BUILD = build
|
||||||
|
|
||||||
|
CC = avr-gcc
|
||||||
|
NM = avr-nm
|
||||||
|
SIZE = avr-size
|
||||||
|
OBJCOPY = avr-objcopy
|
||||||
|
OBJDUMP = avr-objdump
|
||||||
|
|
||||||
|
override CFLAGS = -g -Wall -Os -mmcu=$(TARGET_MCU) -Wa,-gstabs,-adhlns=$(BUILD)/$(*D)/$(*F).lst -MMD -MP -MF $(BUILD)/$(*D)/$(*F).d -pipe
|
||||||
|
override LDFLAGS = -Wl,-Map=$(BUILD)/$(TARGET).map,--cref
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
SRC := $(wildcard *.c)
|
||||||
|
|
||||||
|
all: $(addprefix $(BUILD)/$(TARGET), .elf .lss .sym .bin .hex _eeprom.bin _eeprom.hex)
|
||||||
|
# @$(SIZE) -x -C --mcu=$(TARGET_MCU) $<
|
||||||
|
|
||||||
|
%.lss: %.elf
|
||||||
|
@$(OBJDUMP) -h -S -C $< > $@
|
||||||
|
|
||||||
|
%.sym: %.elf
|
||||||
|
@$(NM) -n $< > $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
@$(OBJCOPY) -j .text -j .data -O binary $< $@
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
@$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||||
|
|
||||||
|
%_eeprom.bin: %.elf
|
||||||
|
@$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ 2> /dev/null
|
||||||
|
|
||||||
|
%_eeprom.hex: %.elf
|
||||||
|
@$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ 2> /dev/null
|
||||||
|
|
||||||
|
$(BUILD)/$(TARGET).elf: $(patsubst %,$(BUILD)/%,$(SRC:.c=.o))
|
||||||
|
@echo " Linking file: $@"
|
||||||
|
@$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) > /dev/null
|
||||||
|
@$(SIZE) -x -B $^ $@
|
||||||
|
|
||||||
|
$(BUILD)/%.o: %.c $(MAKEFILE_LIST)
|
||||||
|
@echo " Building file: $<"
|
||||||
|
@$(shell mkdir -p $(BUILD)/$(*D))
|
||||||
|
@$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD)
|
||||||
|
|
||||||
|
install: $(BUILD)/$(TARGET).hex $(BUILD)/$(TARGET)_eeprom.hex
|
||||||
|
avrdude -c dragon_isp -P usb -p t24 -U flash:w:$(BUILD)/$(TARGET).hex -U eeprom:w:$(BUILD)/$(TARGET)_eeprom.hex
|
||||||
|
|
||||||
|
# no self programming, 2.7V BOD, 8MHz internal RC Osz.
|
||||||
|
fuses:
|
||||||
|
avrdude -c dragon_isp -P usb -p t24 -U lfuse:w:0xc2:m -U hfuse:w:0xdd:m -U efuse:w:0xff:m
|
||||||
|
|
||||||
|
-include $(shell find $(BUILD) -name *.d 2> /dev/null)
|
159
main.c
Normal file
159
main.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 04/2011 by Olaf Rempel *
|
||||||
|
* razzor@kopf-tisch.de *
|
||||||
|
* *
|
||||||
|
* This program 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; version 2 of the License, *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include <avr/sleep.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attiny24: (no self programming, 2.7V BOD, 8MHz internal RC Osz)
|
||||||
|
* LFUSE = 0xC2
|
||||||
|
* HFUSE = 0xDD
|
||||||
|
* EFUSE = 0xFF
|
||||||
|
*
|
||||||
|
* RC5 Input on PB2 (INT0)
|
||||||
|
* PROGMODE Jumper (active low) on PB1
|
||||||
|
* OUTPUT (active low) on PB0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* RC5 bitlength is 1778us +/-10% convert to time0 ticks (8us) */
|
||||||
|
#define BITWIDTH (1778 / 8)
|
||||||
|
#define BITWIDTH_MIN (BITWIDTH - (BITWIDTH / 10))
|
||||||
|
#define BITWIDTH_MAX (BITWIDTH + (BITWIDTH / 10))
|
||||||
|
|
||||||
|
#define RC5_BITCNT 14
|
||||||
|
#define RC5_CMD_MASK 0x37FF
|
||||||
|
#define RC5_COMPLETE 0x8000
|
||||||
|
|
||||||
|
#define PROGMODE_CHECK() (!(PINB & (1<<PINB1)))
|
||||||
|
#define OUTPUT_ON() { PORTA &= ~(1<<PORTA0); }
|
||||||
|
#define OUTPUT_OFF() { PORTA |= (1<<PORTA0); }
|
||||||
|
|
||||||
|
struct ee_param {
|
||||||
|
uint16_t rc5cmd;
|
||||||
|
uint8_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ee_param params;
|
||||||
|
struct ee_param params_in_eeprom EEMEM = {
|
||||||
|
.rc5cmd = 0x350C,
|
||||||
|
.state = 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t bitcnt;
|
||||||
|
static volatile uint16_t value;
|
||||||
|
|
||||||
|
ISR(EXT_INT0_vect)
|
||||||
|
{
|
||||||
|
if (bitcnt == 0)
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
bitcnt++;
|
||||||
|
|
||||||
|
value = (value << 1);
|
||||||
|
if (!(PINB & (1<<PINB2)))
|
||||||
|
value |= 0x0001;
|
||||||
|
|
||||||
|
/* setup sample window for next edge */
|
||||||
|
OCR0A = TCNT0 + BITWIDTH_MIN;
|
||||||
|
OCR0B = TCNT0 + BITWIDTH_MAX;
|
||||||
|
|
||||||
|
/* clear and enable COMPA / COMPB */
|
||||||
|
TIFR0 = (1<<OCF0A) | (1<<OCF0B);
|
||||||
|
TIMSK0 |= (1<<OCIE0A) | (1<<OCIE0B);
|
||||||
|
|
||||||
|
/* disable INT0 until COMPA hits */
|
||||||
|
GIMSK &= ~(1<<INT0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIM0_COMPA_vect)
|
||||||
|
{
|
||||||
|
/* clear and enable INT0 */
|
||||||
|
GIFR = (1<<INTF0);
|
||||||
|
GIMSK |= (1<<INT0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TIM0_COMPB_vect)
|
||||||
|
{
|
||||||
|
/* disable sample window */
|
||||||
|
TIMSK0 &= ~((1<<OCIE0A) | (1<<OCIE0B));
|
||||||
|
|
||||||
|
/* final bit received? */
|
||||||
|
if (bitcnt >= RC5_BITCNT)
|
||||||
|
value |= RC5_COMPLETE;
|
||||||
|
|
||||||
|
bitcnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
/* pullup on RC5IN and PROGMEM, OUTPUT is low active */
|
||||||
|
PORTB = (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0);
|
||||||
|
|
||||||
|
/* INT0: both edges generate interrupt */
|
||||||
|
MCUCR = (1<<ISC00);
|
||||||
|
GIMSK = (1<<INT0);
|
||||||
|
|
||||||
|
/* Timer0: 8Mhz/64 */
|
||||||
|
TCCR0B = (1<<CS01) | (1<<CS00);
|
||||||
|
|
||||||
|
/* load configuration, restore state */
|
||||||
|
eeprom_read_block(¶ms, ¶ms_in_eeprom, sizeof(struct ee_param));
|
||||||
|
if (params.state) {
|
||||||
|
OUTPUT_ON();
|
||||||
|
} else {
|
||||||
|
OUTPUT_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all interrupts can wake up */
|
||||||
|
set_sleep_mode(SLEEP_MODE_IDLE);
|
||||||
|
sei();
|
||||||
|
|
||||||
|
uint16_t old_value = 0x0000;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* wait for next interrupt */
|
||||||
|
sleep_mode();
|
||||||
|
|
||||||
|
if (value & RC5_COMPLETE) {
|
||||||
|
/* PROGMODE jumper set? */
|
||||||
|
if (PROGMODE_CHECK()) {
|
||||||
|
params.rc5cmd = (value & RC5_CMD_MASK);
|
||||||
|
eeprom_write_block(¶ms, ¶ms_in_eeprom, sizeof(struct ee_param));
|
||||||
|
|
||||||
|
/* current command matches stored one */
|
||||||
|
} else if (params.rc5cmd == (value & RC5_CMD_MASK) && value != old_value) {
|
||||||
|
if (params.state) {
|
||||||
|
params.state = 0;
|
||||||
|
OUTPUT_OFF();
|
||||||
|
} else {
|
||||||
|
params.state = 1;
|
||||||
|
OUTPUT_ON();
|
||||||
|
}
|
||||||
|
|
||||||
|
eeprom_write_block(¶ms, ¶ms_in_eeprom, sizeof(struct ee_param));
|
||||||
|
old_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = 0x0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user