/*
 * Direct port manipulation in C
 *
 * Created: 03/11/2022 11:40:59
 * Author : Ben Clifford
 *
 * This is an example program for the EG-151 lecture on
 * Digital I/O using C and shows direct port manipulation
 * using bit masking
 */

/*
 * PORTD maps to Arduino digital pins 0 to 7
 * DDRD - The Port D Data Direction Register - read/write
 * PORTD - The Port D Data Register - read/write
 * PIND - The Port D Input Pins Register - read only
 *
 * PORTB maps to Arduino digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
 * DDRB - The Port B Data Direction Register - read/write
 * PORTB - The Port B Data Register - read/write
 * PINB - The Port B Input Pins Register - read only
 *
 * PORTC maps to Arduino analog pins 0 to 5. Pins 6 & 7 are only accessible on the Arduino Mini
 * DDRC - The Port C Data Direction Register - read/write
 * PORTC - The Port C Data Register - read/write
 * PINC - The Port C Input Pins Register - read only
 */

#include <stdint.h>

// I/O and ADC Register definitions taken from datasheet
#define	PORTD (*(volatile uint8_t *)(0x2B))
#define DDRD  (*(volatile uint8_t *)(0x2A))
#define PIND  (*(volatile uint8_t *)(0x29))

#define PORTB (*(volatile uint8_t *)(0x25))
#define DDRB  (*(volatile uint8_t *)(0x24))
#define PINB  (*(volatile uint8_t *)(0x23))

int main(void) 
{
    // Eqivalent of Arduino IDE sketch subprocess setup()
    //Set Data Direction Registers
    DDRD = DDRD & 0b11110011; //setup bits 2 and 3 of port D as inputs
    DDRB = DDRB | 0b00000011; //setup bits 0 and 1 of port B as outputs

    PORTB = PORTB & 0b11111100; //both pins B0 (D8) and B1 (D9) start low
	
    PORTD = PORTD | 0b00001100; // Enable the pull up resistor for bits 2 and 3 of port D
	
    // Eqivalent of Arduino IDE sketch subprocess loop()
    for(;;) {
        if((PIND & 0b00000100) == 0) {
            PORTB = PORTB | 0b00000001; //sets port B, bit 0 to logic 1/high, switches the LED connected to D8 on
        }
        else if ((PIND & 0b00001000) == 0) {
            PORTB = PORTB | 0b00000010; //sets port B, bit 1 to logic 1/high, switches the LED connected to D9 on
        }
        else {
            PORTB = PORTB & 0b11111100; //sets bits 0-5 of port B to logic 0/low, switches off both the LED's
        }
    }
	
}
$abcdeabcde151015202530354045505560fghijfghij