Subversion Repositories Code-Repo

Rev

Blame | Last modification | View Log | RSS feed

#include "DEFINES.h"
#include "INTERRUPTS.h"
#include "PWM.h"
#include "IOC.h"
#include "EUSART.h"

// <editor-fold defaultstate="collapsed" desc="Configuration Registers">
// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// </editor-fold>

int main() {
    // Initialize oscillator to external crystal (20Mhz)
    OSCCONbits.SCS = 0b00;
    OSCCONbits.SPLLEN = 0b0;
    OSCCONbits.IRCF = 0b1111;

    // Set all pins to digital I/O
    ANSELA = 0x00;
    // Disable pull-ups
    OPTION_REGbits.nWPUEN = 1;
    WPUA = 0x0;

    // Configure alternate pin function register
    APFCONbits.RXDTSEL = 0; // RX on RA1
    APFCONbits.TXCKSEL = 0; // TX on RA0
    APFCONbits.CCP1SEL = 0; // CCP1 on RA2
    
    // Delay for a bit to ensure oscillator has started
    __delay_ms(10);

    // Configure and enable interrupts
    Interrupt_Enable();

    // Configure and enable peripherals
    PWM_Init();
    IOC_Init();
    UART_Init();

    uint8_t recvBuffer[32];
    uint8_t txOk[] = "Ok!\n";
    uint8_t txError[] = "Error!\n";

    /* Protocol format as follows:
     * Byte 0 = OPCODE
     *      0x1 = Set frequency
     *          Bytes 1-4 = 32 bit unsigned value
     *      0x2 = Set duty cycle
     *          Byte 1 = 8 bit unsigned value (high value)
     *          Byte 2 = 8 bit unsigned value (low value)
     *      0x3 = Set pattern
     *          Bytes 1-2 = 16 bit pattern (transmits MSB first)
     *      Everything else = nop
     */

    while(1) {
        uint8_t recvBytes = UART_Read(recvBuffer);
        if (recvBytes != 0) {
            // Process op-code for setting frequency
            if (recvBuffer[0] == 0x1 && recvBytes == 5) {
                uint32_t byte0 = recvBuffer[1];
                byte0 <<= 24;
                uint32_t byte1 = recvBuffer[2];
                byte1 <<= 16;
                uint32_t byte2 = recvBuffer[3];
                byte2 <<= 8;
                uint32_t freq = 0;
                freq |= byte0;
                freq |= byte1;
                freq |= byte2;
                freq |= recvBuffer[4];
                // Ensure that received value falls within working bounds
                if (freq >= 20000 && freq <= 200000) {
                    Set_PWM_Frequency(freq);
                    UART_Write(txOk, 4);
                } else {
                    UART_Write(txError, 7);
                }
                UART_Reset_RX();
            } else if (recvBuffer[0] == 0x2 && recvBytes == 3) {
                // Ensure that received value falls within working bounds
                if (recvBuffer[1] <= 100 && recvBuffer[2] <= 100) {
                    Set_PWM_Duty_Cycle(recvBuffer[1], recvBuffer[2]);
                    UART_Write(txOk, 4);
                } else {
                    UART_Write(txError, 7);
                }
                UART_Reset_RX();
            } else if (recvBuffer[0] == 0x3 && recvBytes == 3) {
                uint16_t byte0 = recvBuffer[1];
                byte0 <<= 8;
                uint16_t pattern = 0;
                pattern |= byte0;
                pattern |= recvBuffer[2];
                Set_PWM_Pattern(pattern);
                UART_Reset_RX();
                UART_Write(txOk, 4);
            } else if (recvBuffer[0] == 0x0 || recvBuffer[0] > 0x03 || recvBytes > 5) {
                UART_Reset_RX();
            }
        }
    }

}