/* * File: main.c * Author: sfokin * * Created on March 17, 2024, 6:05 AM */ #pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD) #pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled) #pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #define _XTAL_FREQ 4000000 #define INPUT_PINS 0b00111011 // Pins: 0,1,3,4,5 #include #include "common.h" #include "main.h" char STATE; char btnState; char ir_command[4]; void __interrupt() handle_interrupt(void) { clear_bit(INTCON, 7); if(test_bit(INTCON, 0)) { handle_IOC(); } if(test_bit(PIR1, 0)) { handle_TMR1(); } set_bit(INTCON, 7); return; } void main(void) { init(); while(1) { sleep(); } return; } static inline void init() { //Configure GPIO CMCON = 7; //Turn off comparator GPIO = 0x0; //Clear GPIO port TRISIO = 0; //Clear TRISIO register ANSEL = 0; //Set all pins to digital IO TRISIO = INPUT_PINS; //Set 0,1,3,4,5 pins as input INTCONbits.GIE = 1; //Allow Global interrupts; INTCONbits.GPIE = 1; //Allow interrupt on pin change clear_bit(OPTION_REG, 7); //Global weak pull-up enable WPU = INPUT_PINS; //Weak pull-up for 0,1,3,4,5 pins IOC = INPUT_PINS; //IOC enable for 0,1,3,4,5 pins ir_command[0] = 0x20; ir_command[1] = 0xDF; } static inline void handle_TMR1() { flip_bit(GPIO, 2); TMR1 = 0; clear_bit(PIR1, 0); } static inline void handle_IOC() { btnState = 0; handle_buttons(0); handle_buttons(1); handle_buttons(3); handle_buttons(4); handle_buttons(5); //Volume up if(test_bit(btnState, 5)) { ir_command[2] = 0x40; ir_command[3] = 0xBF; while(!GP5) send_command(ir_command); } //volume down if(test_bit(btnState, 4)) { ir_command[2] = 0xC0; ir_command[3] = 0x3F; while(!GP4) send_command(ir_command); } //input select if(test_bit(btnState, 3)) { ir_command[2] = 0xD0; ir_command[3] = 0x2F; while(!GP3) send_command(ir_command); } //Ok if(test_bit(btnState, 1)) { ir_command[2] = 0x22; ir_command[3] = 0xDD; while(!GP1) send_command(ir_command); } //Power if(test_bit(btnState, 0)) { ir_command[2] = 0x10; ir_command[3] = 0xEF; while(!GP0) send_command(ir_command); } clear_bit(INTCON, 0); } static inline void sleep() { //prepare and go to sleep GP2 = 0; //Turn off led SLEEP(); } static inline void handle_buttons(char bit) { clear_bit(btnState, bit); if(!test_bit(GPIO, bit)) { __delay_ms(10); } if(!test_bit(GPIO, bit)) { set_bit(btnState, bit); } } static inline void send_command(char *command) { send(183); __delay_us(4400); GP2 = 0; send_byte(command[0]); send_byte(command[1]); send_byte(command[2]); send_byte(command[3]); send(9); __delay_ms(200); } static inline void send_byte(char byte) { char mask = 0b10000000; for(char k=0; k<8; k++) { send(13); if((byte & (mask >> k)) == 0) { __delay_us(400); } else { __delay_us(1500); } } } static inline void send(int x) { for(int i = 0; i < x; i++) { GP2=1; __delay_us(26); GP2=0; } }