#include <p32xxxx.h>
#include <sys/attribs.h>

// 外部の8MHz水晶発振器から40MHzのクロックを生成するための設定
#pragma config FNOSC = PRIPLL // 発信源 = 主外部発振器
#pragma config POSCMOD = XT // 主発振の方法　= 外部高精度発振器を使う
#pragma config FPLLIDIV = DIV_2 // PLL入力分数 = x1/2
#pragma config FPLLMUL = MUL_20 // PLL逓倍比 = x20
#pragma config FPLLODIV = DIV_2 // PLL出力分数 = x1/2
#pragma config FPBDIV = DIV_2 //周辺モジュールクロック倍数 : x1/2

char str[51]; int sp = 0;

void sendString(const char *s, int slen)
{
    int i;
     for(i = 0; i < slen; i++){
        U1TXREG = s[i];
        while(U1STAbits.UTXBF) ; // バッファに空きが出るまで待機
    }
}

void __ISR(_UART_1_VECTOR, IPL4AUTO) OnUartReceiving(void) 
{
    IFS1bits.U1RXIF = 0; // UART1受信フラグのリセット

    if(U1STAbits.URXDA == 0) return; // バッファが空の状態なら何もしない
    str[sp] = (char)U1RXREG; // 受信データバッファのデータを格納
    
    // 改行コードを受信するかバッファがいっぱいになったら
    if(str[sp] == '\n' || sp > 50){
        // 受け取ったデータをそのまま返す
        sendString(str, sp + 1);
        sp = 0;
    }else{
        sp++;
    }
}

int main(void)
{
    ANSELB = 0x00;        // ポートBをすべてデジタルモードにする

    U1RXRbits.U1RXR = 0b0100; // UART1/RXにB2を
    RPB3Rbits.RPB3R = 0b0001; // B3をUART1/TXに
    
    U1STAbits.UTXEN = 1;  // UART1の送信を有効
    U1STAbits.URXEN = 1;  // UART1の受信を有効
    U1BRG = 129;          // ボーレート9600 [20M/(16*9600)-1]
    
    U1MODEbits.ON = 1;   // UART1を有効
    IPC8bits.U1IP = 4;   // UART1優先割り込み度
    IPC8bits.U1IS = 3;   // UART1副優先度
    
    IFS1bits.U1RXIF = 0; // UART1受信フラグのリセット
    IFS1bits.U1TXIF = 0; // UART1送信フラグのリセット
    
    IEC1bits.U1RXIE = 1; // UART1受信完了割り込みを有効
    IEC1bits.U1TXIE = 0; // UART1送信完了割り込みを無効
    
    INTCONbits.MVEC = 1;  // マルチベクタ割り込みを有効にする
       
    __builtin_enable_interrupts();  // マイコンにおける割り込みの有効

    sendString("Hello!\n", 7);

    while(1) ;
}