diff --git a/boards/relaycard.mk b/boards/relaycard.mk new file mode 100644 index 0000000..682c7e7 --- /dev/null +++ b/boards/relaycard.mk @@ -0,0 +1,7 @@ +include boards/nano.mk + +CPPFLAGS += -DBAUDRATE=$(AVRDUDE_BAUD) + +ifndef PROG +PROG = uart-relaycard +endif diff --git a/uart-relaycard.c b/uart-relaycard.c new file mode 100644 index 0000000..78deee6 --- /dev/null +++ b/uart-relaycard.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include + +#define BAUD_PRESCALE (((F_CPU/(BAUDRATE*8UL)))-1) + +/* Button matrix between PB3-PB4, PC0-PC3 + * PC0-PC3 are inputs, default pull-up + * PB3-PB4 are pulled to ground (alternating) while the above are read + */ + +uint8_t getButtonState() { + uint8_t val = 0; + + // Pull upper button line (PB4) down + PORTB |= (1 << PB3); + PORTB &= ~(1 << PB4); + _delay_ms(1); + val = ((~PINC) << 4); + + // Pull lower button line (PB3) down + PORTB &= ~(1 << PB3); + PORTB |= (1 << PB4); + _delay_ms(1); + val |= (~PINC) & 0x0F; + + return val; +} + +uint8_t getrelay(uint8_t n) { + uint8_t v = 0; + switch(n) { + case 0: v = (PIND >> PD2); break; + case 1: v = (PIND >> PD3); break; + case 2: v = (PIND >> PD4); break; + case 3: v = (PIND >> PD5); break; + case 4: v = (PIND >> PD6); break; + case 5: v = (PIND >> PD7); break; + case 6: v = (PINB >> PB0); break; + case 7: v = (PINB >> PB1); break; + } + return(~v & 1); +} + +void setrelay(uint8_t n, uint8_t s) { + if (s) { + switch(n) { + case 0: PORTD &= ~(1 << PD2); break; + case 1: PORTD &= ~(1 << PD3); break; + case 2: PORTD &= ~(1 << PD4); break; + case 3: PORTD &= ~(1 << PD5); break; + case 4: PORTD &= ~(1 << PD6); break; + case 5: PORTD &= ~(1 << PD7); break; + case 6: PORTB &= ~(1 << PB0); break; + case 7: PORTB &= ~(1 << PB1); break; + } + } else { + switch(n) { + case 0: PORTD |= (1 << PD2); break; + case 1: PORTD |= (1 << PD3); break; + case 2: PORTD |= (1 << PD4); break; + case 3: PORTD |= (1 << PD5); break; + case 4: PORTD |= (1 << PD6); break; + case 5: PORTD |= (1 << PD7); break; + case 6: PORTB |= (1 << PB0); break; + case 7: PORTB |= (1 << PB1); break; + } + } +} + +char umode = 't'; +ISR(USART_RX_vect) { + uint8_t c = UDR0; + if (c == 't' || c == 'e' || c == 'd') { + umode = c; + } else if (c >= '0' && c <= '7') { + c = c - '0'; + if (umode == 'e') { + setrelay(c,1); + } else if (umode == 'd') { + setrelay(c,0); + } else if (umode == 't') { + setrelay(c,1 - getrelay(c)); + } + } +} + +int main() { + DDRC &= ~(0b1111); // This sets PC0 to PC3 to input + PORTC |= 0b1111; // This makes said pins pull-up per default + + DDRB |= (1 << PB3) | (1 << PB4); // Keypad rows + + DDRD |= 0b11111100; // PD2 to PD7 for relay + DDRB |= 0b00000011; // PB0 and PB1 for relay + + // Same with PORT, so relays stay off + PORTD |= 0b11111100; + PORTB |= 0b00000011; + + // Init uart + UCSR0A = (1<