prgKbd-keyboard/firmware/lib/prgKeyboard.c

275 lines
6.0 KiB
C
Executable File

#include <avr/io.h>
#include <util/delay.h>
#include "prgKeyboard.h"
// General hardware
void initPorts(void) {
// LEDs
LED_DDR |= (1 << LED_RED);
LED_DDR |= (1 << LED_GREEN);
LED_PORT &= ~(1 << LED_RED); // switch 'em off
LED_PORT &= ~(1 << LED_GREEN);
// Keypad
// X-Axis
// Set Keypad X-Axis as inputs
Keypad_DDR_X &= ~(1 << Keypad_X1) & ~(1 << Keypad_X2) & ~(1 << Keypad_X3) & ~(1 << Keypad_X4);
// And enable the pullups
Keypad_PORT_X |= (1 << Keypad_X1) | (1 << Keypad_X2) | (1 << Keypad_X3) | (1 << Keypad_X4);
// Y-Axis
// Set Keypad Y-Axis as outputs
Keypad_DDR_Y |= (1 << Keypad_Y1) | (1 << Keypad_Y2) | (1 << Keypad_Y3) | (1 << Keypad_Y4);
// And set 'em all to high (no keypressses will be registered)
Keypad_PORT_Y |= (1 << Keypad_Y1) | (1 << Keypad_Y2) | (1 << Keypad_Y3) | (1 << Keypad_Y4);
// MODE
Keypad_MDDDR &= ~(1 << Keypad_MD); // Set it as input
Keypad_MDPORT |= (1 << Keypad_MD); // Enable pullup
// EEPROM (24lc64)
// !!! Write protection cannot be used because of an error in the circuit !!!
EEPROM_PORT |= (1 << EEPROM_SDA); //pullups
EEPROM_PORT |= (1 << EEPROM_SCL);
return;
}
uint8_t getKey() {
// Check for the MODE-Button
if (!(Keypad_MDPIN & (1 << Keypad_MD))) return Key_MODE; // MODE PRESSED
// First make sure all bits except the first one are high
Keypad_PORT_Y |= (1 << Keypad_Y2) | (1 << Keypad_Y3) | (1 << Keypad_Y4);
// Now clear the first one so that it's able to pull the pressed bit low
Keypad_PORT_Y &= ~(1 << Keypad_Y1); KEYDELAY
if (!(Keypad_PIN_X & (1 << Keypad_X1))) return 1;
if (!(Keypad_PIN_X & (1 << Keypad_X2))) return 2;
if (!(Keypad_PIN_X & (1 << Keypad_X3))) return 3;
if (!(Keypad_PIN_X & (1 << Keypad_X4))) return 4;
Keypad_PORT_Y |= (1 << Keypad_Y1); // first high
Keypad_PORT_Y &= ~(1 << Keypad_Y2); KEYDELAY // second low
if (!(Keypad_PIN_X & (1 << Keypad_X1))) return 5;
if (!(Keypad_PIN_X & (1 << Keypad_X2))) return 6;
if (!(Keypad_PIN_X & (1 << Keypad_X3))) return 7;
if (!(Keypad_PIN_X & (1 << Keypad_X4))) return 8;
Keypad_PORT_Y |= (1 << Keypad_Y2); // second high
Keypad_PORT_Y &= ~(1 << Keypad_Y3); KEYDELAY // third low
if (!(Keypad_PIN_X & (1 << Keypad_X1))) return 9;
if (!(Keypad_PIN_X & (1 << Keypad_X2))) return 10;
if (!(Keypad_PIN_X & (1 << Keypad_X3))) return 11;
if (!(Keypad_PIN_X & (1 << Keypad_X4))) return 12;
Keypad_PORT_Y |= (1 << Keypad_Y3); // third high
Keypad_PORT_Y &= ~(1 << Keypad_Y4); KEYDELAY // forth low
if (!(Keypad_PIN_X & (1 << Keypad_X1))) return 13;
if (!(Keypad_PIN_X & (1 << Keypad_X2))) return 14;
if (!(Keypad_PIN_X & (1 << Keypad_X3))) return 15;
if (!(Keypad_PIN_X & (1 << Keypad_X4))) return 16;
// if nothing is pressed
return 0;
}
// 24LC64
void EEOpen()
{
//Set up TWI Module
TWBR = 5;
TWSR &= (~((1<<TWPS1)|(1<<TWPS0)));
}
uint8_t EEWriteByte(uint16_t address,uint8_t data)
{
do
{
//Put Start Condition on TWI Bus
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x08)
return FALSE;
//Now write SLA+W
//EEPROM @ 00h
TWDR=0b10100000;
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
}while((TWSR & 0xF8) != 0x18);
//Now write ADDRH
TWDR=(address>>8);
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x28)
return FALSE;
//Now write ADDRL
TWDR=(address);
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x28)
return FALSE;
//Now write DATA
TWDR=(data);
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x28)
return FALSE;
//Put Stop Condition on bus
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
//Wait for STOP to finish
while(TWCR & (1<<TWSTO));
//Wait untill Writing is complete
_delay_ms(12);
//Return TRUE
return TRUE;
}
uint8_t EEReadByte(uint16_t address)
{
uint8_t data;
//Initiate a Dummy Write Sequence to start Random Read
do
{
//Put Start Condition on TWI Bus
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x08)
return FALSE;
//Now write SLA+W
//EEPROM @ 00h
TWDR=0b10100000;
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
}while((TWSR & 0xF8) != 0x18);
//Now write ADDRH
TWDR=(address>>8);
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x28)
return FALSE;
//Now write ADDRL
TWDR=(address);
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x28)
return FALSE;
//*************************DUMMY WRITE SEQUENCE END **********************
//Put Start Condition on TWI Bus
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x10)
return FALSE;
//Now write SLA+R
//EEPROM @ 00h
TWDR=0b10100001;
//Initiate Transfer
TWCR=(1<<TWINT)|(1<<TWEN);
//Poll Till Done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x40)
return FALSE;
//Now enable Reception of data by clearing TWINT
TWCR=(1<<TWINT)|(1<<TWEN);
//Wait till done
while(!(TWCR & (1<<TWINT)));
//Check status
if((TWSR & 0xF8) != 0x58)
return FALSE;
//Read the data
data=TWDR;
//Put Stop Condition on bus
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
//Wait for STOP to finish
while(TWCR & (1<<TWSTO));
//Return TRUE
return data;
}