RX62N 開発

# 使ったボード

![1646152679947.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/fa90d9bc-a49b-d18b-038e-eb54c5bdfe28.jpeg)

雑誌の付録．
当時はHEWを利用して開発するのが主流だったようだが，Windows10マシンにHEWを入れるのは気が引けるので，e2studio + gcc（Renesas拡張） をメインに進めたい．
ボードにはレギュレータやUSB（残念ながらmini USB）など一通り必要なものは付いているので，USBケーブル1本で始められる．

## SoCはRX62N　144Pin
SoCとして，R5F562N7BDFBが付いている．
CPUコアはRXv1で，最高動作周波数は100MHz．

144ピンのSoCで，I/Oは103ピンあり，
入力プルアップ抵抗内蔵：ポート9，A，B，C，D，E，G
オープンドレイン出力：ポート0，1，2，3（P30～P34），C
5Vトレラント対応端子：ポート0（P00，P01，P02，P07），ポート1（P12，P13，P16，P17），ポート2（P20，kP21），ポート3（P33）
（上記ボードには12MHzの水晶が載っている）


# 開発環境
- Windows10
- e2studio(gnurx)
- Renesas Flash Programmer V3.01

　少し古いSoCなので，e2studio+gnurxでの開発情報がなかなか見つけられない（当時はHEW）．動作確認が取れた方法を，ここに記しておく．

## PCとはUSBケーブルで接続する
　このSoCはUSB接続でプログラムを書き込む機能が付いている（DFUみたいなものか？）

![rx1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/e85c36fe-2b60-c9b1-fa77-f90d4f59e0e3.png)

MD0ピンをGNDに落とした状態でリセットすると，Bootモードになる．その状態でデバイスマネージャーに上記のデバイスが表示されれば，Windowsに認識されている．
ボードへの電源供給も，USBから行える．

# e2studioでプロジェクトを作る
## まずはLチカ
　まずはLチカで動作を確かめる．ボード上にチップLEDが1つ用意されている．P15に接続されている．
以下，ソースコードの抜粋．

```c
int main(void) {
	  PORT1.DDR.BIT.B5 = 1;

    while(1) {
    	PORT1.DR.BIT.B5 ^= 1;
	    for(int i=0; i < 1000000; i++);
	// TODO: add application code here
    }
return 0;
}
```


　Lチカするソースコードをe2studioに用意し，Renesas Flash Programmerで書き込んでみる．
### e2studioでプロジェクトを作りビルドする
　「プロジェクト」-「プロパティ」と開き，下記の様にコンパイラを指定してから，ビルドする．
　HardwareDebugフォルダに生成物ができる．
![rxa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/1f242eee-dfe7-935f-1118-c74ffcb1229b.png)


### Renesas Flash Programmerで書き込む
#### 1：プロジェクトを作る（e2studioのプロジェクトとは関係ない）
![rx2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/52d19b69-1a37-c68a-1f9d-9203f8c87d2d.png)

#### 2：ツールはUSB Directを選ぶ
![rx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/c276d1f5-7d59-1b58-28c2-7c4b44586fa3.png)

#### 3： メインクロックを設定する
![rx5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/71c6aa3b-1eee-7c48-2de8-006c753b0170.png)

#### 4：接続に成功した画面（まだプログラムは書き込んでいない）
　プログラムファイルとして`.mot`形式のファイルを選択し，「スタート」をクリックすると書き込める．
![rx6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/af304cb1-22d0-a6e9-feb5-e2039629dbdf.png)





# サンプル・プログラム
## サンプル：タイマーでLチカ

```main.c
#include <iodefine.h>
#include <interrupt_handlers.h>

#define PCLK    48
volatile unsigned int utimer;

void initTimer(void){
    MSTP(CMT1) = 0;
    CMT1.CMCR.WORD = 0x0040;
    CMT1.CMCOR = PCLK*1000000L/1000000L/8L - 1;
    ICU.IER[IER_CMT1_CMI1].BIT.IEN_CMT1_CMI1 = 1;
    ICU.IPR[IPR_CMT1_CMI1].BYTE = 8;priority level
    CMT.CMSTR0.WORD |= 0x0002;
    utimer = 0;
}

unsigned int getTimer(void){
    return utimer;
}

void delay_us(unsigned int us){
    utimer = 0;
    while(utimer <= us);
}

void init(){
	PORT1.DDR.BIT.B5 = 1;  //On Board LED
}

int main(void) {
	init();
	initTimer();

    while(1) {
   		PORT1.DR.BIT.B5 ^= 1;
    	delay_ms(1000);
    }
    return 0;
}
```

```inthandler.c
extern unsigned int utimer;
：
//;0x0074  CMTU0_CMT1
void  INT_Excep_CMT1_CMI1(void){utimer++; }
：
```

## サンプル：キャラクタ・ディスプレイSC1602
### デバイス
　家に一杯あったので[これ](https://akizukidenshi.com/catalog/g/gP-00040/)を使った．5V品だったので，Write専用で使うことにする．
　上記「タイマーでLチカ」の，タイマー部分を切り出し`timer.c`と`timer.h`とした．

### LCDドライバ
　参考サイト（4）を参考にさせていただいて，ポーティングした．

```lcd.c

#include "lcd.h"
#include "timer.h"
#include <iodefine.h>

void DelayTCYx(int tick){
	delay_us(tick);
}

void lcd_init(void){
    DelayTCYx(15000);  //  15ms*(48MHz/4)=180,000

    LCD_RS=0;
    lcd_out4( LCD_FUNCM | LCD_8BIT ); //  8bit
    DelayTCYx(5000);  //   5ms*(48MHz/4)= 60,000

    lcd_out4( LCD_FUNCM | LCD_8BIT ); //  8bit
    DelayTCYx(4000);  //   4ms*(48MHz/4)= 48,000

    lcd_out4(  LCD_FUNCM | LCD_8BIT ); //  8bit
    DelayTCYx(4000);  //   4ms*(48MHz/4)= 48,000

    lcd_out4( LCD_FUNCM | LCD_4BIT); //  4bit
    DelayTCYx(4000);  //   4ms*(48MHz/4)= 48,000

    lcd_out8( LCD_FUNCM | LCD_4BIT | 0b1000 );
    DelayTCYx(4000);  //   4ms*(48MHz/4)= 48,000

    lcd_out8( LCD_DISPM | LCD_DISPON | LCD_CURON | LCD_BLINKOFF );
    DelayTCYx( 167);

    lcd_out8( LCD_ENTRYM | LCD_INC | LCD_NONSHIFT);
    DelayTCYx( 167);  //  0.167ms*(48MHz/4)=  2,000

    lcd_clear();
}

void lcd_clear(void){
    LCD_RS=0;
    lcd_out8( LCD_CLEAR );
    DelayTCYx(2000);  //  2ms*(48MHz/4)=  24,000
}

void lcd_en(unsigned char d){
    LCD_RS=0;
    lcd_out8( LCD_DISPM | d);
    DelayTCYx(40);  //  40μs*(48MHz/4)=  480
}

void lcd_puts(const char* buf){
    LCD_RS=1;
    while(*buf){
        lcd_out8(*buf);
        DelayTCYx(50);  //  50μs*(48MHz/4)=  600
        ++buf;
    }
}

void lcd_putc(unsigned char c){
    LCD_RS=1;
    lcd_out8(c);
    DelayTCYx(50);  //  50μs*(48MHz/4)=  600
}

void lcd_ddram(unsigned char ads){
    LCD_RS=0;
    lcd_out8( LCD_DDADS | ads );
    DelayTCYx(40);  //  40μs*(48MHz/4)=  480
}

void lcd_ddramxy(unsigned char x,unsigned char y){
    unsigned char ads = 0x40*y - (2<=y ? (0x40*2-0x14) : 0)+x;
    lcd_ddram(ads);
}

void lcd_cgram(unsigned char ads,unsigned char* buf){
    LCD_RS=0;
    lcd_out8( LCD_CGADS | ads );
    DelayTCYx(40);  //  40μs*(48MHz/4)=  480
    LCD_RS=1;
    for(int n=0;n<8;n++){
       lcd_out8( buf[n] );
        DelayTCYx(40);  //  40μs*(48MHz/4)=  480
    }
}

void lcd_disp(const unsigned char* buf){
    const unsigned char* p=buf;
    unsigned char x=0;
    unsigned char y=0;
    LCD_RS=0;
    lcd_out8( LCD_CURHOME );
    DelayTCYx(2000);  //  2ms*(48MHz/4)=  24,000

    LCD_RS=1;
    while(*p){
        if(x==LCD_CMAX || *p=='\n'){
            ++y;
            lcd_ddramxy(0,y);
            DelayTCYx(50);  //  50μs*(48MHz/4)=  600
            LCD_RS=1;
            x=0;
        }
        if(*p!='\n'){
            lcd_out8(*p);
            DelayTCYx(50);  //  50μs*(48MHz/4)=  600
            ++x;
        }
        ++p;
   }
}

void lcd_out4(unsigned char data){
    unsigned char t1;
    PORT6.DR.BIT.B7 = (data & 0x20) >> 5;
    PORT6.DR.BIT.B6 = (data & 0x40) >> 6;
    PORT6.DR.BIT.B5 = (data & 0x80) >> 7;
    PORT0.DR.BIT.B1 = (data & 0x10) >> 4;

    LCD_E=1;
    DelayTCYx(5);
    LCD_E=0;
}

void lcd_out8(unsigned char data){
    lcd_out4(data);
    lcd_out4(data<<4);
}
```

## サンプル：PWM
### MTU4
　MTU4は，主に相補PWMなどで使うチャネルのようである．
　幾つかモードがある．ここではシンプルなPWMモード1（P.939）で使う．
このモードでは2つのレジスタを使い，Duty比とサイクルタイム（PWM周波数の逆数）を設定する．

　試した感じでは，MTIOC4A-A端子からモード1でPWM信号を出すだけでも，`MTU4.TIORH.BIT.IOB=0x01`の設定が必須だった．

#### 関係するレジスタ
| iodefine.hのレジスタ名 | 通称 | 機能 | ページ |
|--|--|--|--|
| MTUA.TRWER.BIT.RWE | RWE | レジスタ書込み許可 | 984 |
| MTUA.TSTR.BIT.CST4 | CST4 | 1でタイマスタート |
| MTUA.TOER.BIT.OE4A | OE4A| MTU出力許可（MTIOC4A） | 903 |
| IOPORT.PFCMTU.BIT.MTUS4| MTUS4 | |
| MTU4.TCR.BIT.CCLR | CCLR | カウンタクリア選択 | 873 |
| MTU4.TCR.BIT.CKEG | CKEG | カウントエッジ選択（立上り/立下り） | 873 |
| MTR4.TCR.BIT.TPSC | TPSC | タイマプリスケーラ選択 | 873, 875 |
| MTU4.TCNT | TCNT | カウンタ |
| MTU4.TMDR.BIT.MD | | タイマの動作モード選択 | 876 |
| MTU4.TIORH.BIT.IOA | IOA | MTIOC4A端子の機能（コンペアマッチでHigh/Low/トグル/出力禁止） | 878, 886 |
| MTU4.TIORH.BIT.IOB | IOB | MTIOC4B端子の機能 | 878, 882 |
| MTU4.TIORL.BIT.IOC | IOC | MTIOC4C端子の機能 | 887 |
| MTU4.TGRA | TGRA | コンペアマッチのターゲット |
| MTU4.TGRB | TGRB | コンペアマッチのターゲット |
| MTU4.TGRC | TGRC | コンペアマッチのターゲット |

#### プログラム
```main.c
void pwm4_init(){
	MTUA.TRWER.BIT.RWE = 1;  //レジスタ書込み禁止解除
	MSTP(MTU4) = 0;  //MTU4電源ドメインON

	MTUA.TSTR.BIT.CST4 = 0;  //タイマを停止
	MTUA.TOER.BIT.OE4A = 1;  //MTIOC4A選択
	IOPORT.PFCMTU.BIT.MTUS4 = 0;
    MTU4.TCR.BIT.TPSC = 0x02;
    MTR4.TCR.BIT.CKEG = 0x00;      //立ち上がりカウント選択
    MTR4.TCR.BIT.CCLR = 0x01;      //TGRBのコンペアマッチでクリア
	MTU4.TCNT = 0x0000;

	MTU4.TMDR.BYTE = 0x02;         //PWMモード1

	MTU4.TIORH.BIT.IOA = 0x01;     //カウンタリセット
	MTU4.TIORH.BIT.IOB = 0x02;     //
	MTU4.TIORL.BIT.IOC = 0x00;

	MTU4.TGRA = 0x0600;            //PWMサイクル設定
	MTU4.TGRB = 0x0300;            //Duty設定
	//MTU4.TGRC = 0x0600;

	MTUA.TSTR.BIT.CST4 =1;  //タイマスタート
}
```

## サンプル：UART

Renesasアプリケーションノート‥（1）
https://www.renesas.com/us/ja/document/apn/934691
SCI0でUARTを使う解説‥（2）
https://blog.goo.ne.jp/lm324/e/29f9d9a1c17cd38d2f4261e1b0ac4652

（2）のページで紹介されているプログラムを利用させていただく．
以下の割り込み関数を`inthandler.c`に移す．
　void  INT_Excep_SCI0_ERI0(void)
　void  INT_Excep_SCI0_RXI0(void)
　void  INT_Excep_SCI0_TXI0(void)
関連する変数を`inthandler.c`内でextern宣言する．

　SCI0は，`GPIO20`（TxD0）37ピンと`GPIO21`（RxD0）36ピンに割り当てられている．これらは5VトレラントなのでUSB-シリアル変換などで動作確認しやすい．

## サンプル：ADC
　ソフトウェア・スタートでADCを使う．`AD0.ADCSR.BIT.ADST=1`によってワンショットでADCする．
ADCできると`AD0.ADCSR.BIT.ADST==0`になる．

#### 関係するレジスタ
| iodefine.hのレジスタ名 | 通称 | 機能 | ページ |
|--|--|--|--|
| AD0.ADCSR.BIT.CH | CH | ADチャネル設定 | 1708 |
| AD0.ADCSR.BIT.ADST | ADST | ADスタート | 1708 |
| AD0.ADCR.BIT.MODE | MODE | 動作モード選択 | 1710 |
| AD0.ADCR.BIT.CKS | CKS | クロック選択 | 1710 |
| AD0.ADCR.BIT.TRGS | TRGS | トリガ選択 | 1710 |
| AD0.ADDPR.BIT.DPSEL | DPSEL | LSB/MSB選択 | 1711 |
| AD0.ADDRA | ADDR | データレジスタ（AN0） | 1707 |
| AD0.ADDRB | ADDR | データレジスタ（AN1） | 1707 |
| AD0.ADDRC | ADDR | データレジスタ（AN2） | 1707 |
| AD0.ADDRD | ADDR | データレジスタ（AN3） | 1707 |

### プログラム

```main.c
void initAD(){
	MSTP(AD0) = 0;
	AD0.ADCSR.BIT.CH = 0x01;  //for using AN1
	AD0.ADCR.BIT.MODE = 0x00;
	AD0.ADCR.BIT.CKS = 0x03;
	AD0.ADDPR.BIT.DPSEL = 0;  //LSB
}

int main(void) {
	initAD();

    while(1) {
    	/* ADC */
        AD0.ADCSR.BIT.ADST = 1;     //ADC Start
        for(int i=0; i<100; i++);
        for(; AD0.ADCSR.BIT.ADST;)  //Waiting for ADC done
        	for(int i=0; i<100; i++);
        contrastAD = AD0.ADDRB >> 2;
        float rating = contrastAD / 256.0f;
    }
    return 0;
}
```

## サンプル：USB　PCDC（USB UART）
　Renesasのサンプル・プログラムを動かす．日本語ドキュメントが付属しており，プログラムの動きの解説がとても分かりやすい．ただし，サンプルのe2studio用プロジェクトはコンパイラがCCRXとなる．

●RXファミリ USB Peripheral Communication Device Class Driver (PCDC)
https://www.renesas.com/jp/ja/document/scd/rx-family-usb-peripheral-communication-device-class-driver-pcdc-sample-code?language=ja&r=1054421

このサンプルは，「RX62NのUART」と「RX62NのUSB PCDC」間でテキストをフォワードするもの．
ダウンロードデータ内には，サンプルプログラムの流れが分かりやすく書いてあるので，読んでおくとよい．
　サンプルには，`ECHO`と`UART`という2つが含まれている．

　ここでは，`UART`サンプルを利用する．まずRXが外部とUARTで通信する処理を削除する．そしてUSB経由（UART）でPCのターミナルにメッセージを投げられる機能だけを残す．ついでに関数化してmainループから利用しやすくする．
USBケーブルだけでデバッグメッセージを表示できるようになるので便利です．

![rx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/6cae228d-5207-0332-08cc-902e1b1b37f1.png)


### 作り方
　「RXファミリ USB Peripheral Communication Device Class Driver (PCDC)」をダウンロードし，e2studioでプロジェクトを読み込む．

複数のRenesas提供のサンプルプログラムを使っていると，プロジェクト名が，被ってしまうので，名称を変えておく（どのサンプルもプロジェクト名が全部RX62Nなので，変えておかないと新しいものを読み込めなくなる）．
![usb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/23d6defc-7503-fac9-560e-d7985bc16f51.png)

　`r_usb_pcdc_uart_apl.h`，`r_usb_pcdc_uart_apl.c`，`main.c`を編集する．
　前述の通り，2つのサンプルから選択する．具体的には`r_usb_pcdc_apl_config.h`のサンプル選択の`#define`行を`#define OPERATION_MODE  (USB_UART)`とする．
　CCRXでコンパイル．

### API
　次のように関数化した．
| API | 機能 | ファイル |
|--|--|--|
| void usb_init(void) | 初期化 | r_usb_pcdc_apl.c |
| void usb_loop(void) | ループ処理（定期的に呼ぶ） | r_usb_pcdc_apl.c |
| uint8_t usb_message[32] | USB-UART経由で投げるメッセージ | r_usb_pcdc_apl.c |


```r_usb_pcdc_apl.h
#include <string.h>

#include "r_usb_basic_if.h"
#include "r_usb_pcdc_if.h"
#include "r_usb_pcdc_apl_config.h"

#if defined(USE_LPW)
#include "r_usb_rsk_lowpower.h"
#endif /* defined(USE_LPW) */

#define NUM_STRING_DESCRIPTOR (7u)

#define USB_ECHO                (0)             /* Loop back(Echo) mode */
#define USB_UART                (1)             /* USB Serial(VCOM) converter mode */

#define DATA_LEN                (64)

/* LINE_CODING request wLength */
#define LINE_CODING_LENGTH     (0x07u)

extern uint8_t g_apl_device[];
extern uint8_t g_apl_configuration[];
extern uint8_t *g_apl_string_table[];

void usb_init (void);
void usb_loop(void);
```


```r_usb_pcdc_uart_apl.c
#include    "r_usb_pcdc_apl.h"
#include "stdio.h"

#if OPERATION_MODE == USB_UART
#include "r_sci_rx_if.h"
#include "r_usb_rsk_sci.h"

static void apl_init(void);

static void usb_pin_setting(void);
static uint8_t g_usb_data[DATA_LEN];
static uint8_t g_sci_data[DATA_LEN];

static uint8_t g_is_usb_bulk_writing;
static uint8_t g_is_usb_interrupt_writing;
static usb_pcdc_linecoding_t g_line_coding;

const static usb_descriptor_t usb_descriptor = { g_apl_device, /* Pointer to the device descriptor */
g_apl_configuration, /* Pointer to the configuration descriptor for Full-speed */
USB_NULL, /* Pointer to the configuration descriptor for Hi-speed */
USB_NULL, /* Pointer to the qualifier descriptor */
g_apl_string_table, /* Pointer to the string descriptor table */
NUM_STRING_DESCRIPTOR };

uint8_t g_is_serial_state;
uint8_t g_serial_state[2];

sci_hdl_t console;

void R_USB_PinSet_USB0_PERI(void);
void R_USB_PinSet_USB1_PERI(void);

usb_ctrl_t ctrl;
usb_cfg_t cfg;
usb_err_t err;

uint8_t usb_message[32] = "";

void usb_init(void) {

	apl_init(); /* Application program initialization */
	usb_pin_setting(); /* USB MCU pin setting */

	USB_RSK_SCI_INIT();

	ctrl.module = USE_USBIP;
	ctrl.type = USB_PCDC;
	cfg.usb_speed = USB_SUPPORT_SPEED; /* USB_HS/USB_FS */
	cfg.usb_mode = USB_PERI;
	cfg.p_usb_reg = (usb_descriptor_t*) &usb_descriptor;
	R_USB_Open(&ctrl, &cfg); /* Initializes the USB module */
}

void usb_loop(void) {
	switch (R_USB_GetEvent(&ctrl)) {
	case USB_STS_CONFIGURED:
		g_is_usb_bulk_writing = USB_NO;
		g_is_usb_interrupt_writing = USB_NO;
		ctrl.type = USB_PCDC;
		R_USB_Read(&ctrl, g_usb_data, DATA_LEN);
		break;

	case USB_STS_WRITE_COMPLETE:
		if (USB_PCDC == ctrl.type) {
			/* Bulk IN(CDC data) transfer has been completed */
			g_is_usb_bulk_writing = USB_NO;
		} else {
			/* Interrupt IN(SerialState) transfer has been completed */
			g_is_usb_interrupt_writing = USB_NO;
		}
		break;

	case USB_STS_REQUEST: /* Receive Class Request */
		if (USB_PCDC_SET_LINE_CODING == (ctrl.setup.type & USB_BREQUEST)) {
			ctrl.type = USB_REQUEST;
			R_USB_Read(&ctrl, (uint8_t*) &g_line_coding, LINE_CODING_LENGTH);
		} else if (USB_PCDC_GET_LINE_CODING
				== (ctrl.setup.type & USB_BREQUEST)) {
			ctrl.type = USB_REQUEST;
			R_USB_Write(&ctrl, (uint8_t*) &g_line_coding, LINE_CODING_LENGTH);
		} else {
		}
		break;

	case USB_STS_REQUEST_COMPLETE: /* Complete Class Request */
		if (USB_PCDC_SET_LINE_CODING == (ctrl.setup.type & USB_BREQUEST)) {
			/* RS-232C Line set.(Parameter : line_coding) */
			usb_cpu_Sci_Set1(&g_line_coding);
		} else if (USB_PCDC_GET_LINE_CODING
				== (ctrl.setup.type & USB_BREQUEST)) {
			/* none */
		} else if (USB_PCDC_SET_CONTROL_LINE_STATE
				== (ctrl.setup.type & USB_BREQUEST)) {
		} else {
		}
		break;

	case USB_STS_SUSPEND:
	case USB_STS_DETACH:
#if defined(USE_LPW)
		low_power_mcu();
#endif /* defined(USE_LPW) */
		break;

	case USB_STS_NONE:
		if (USB_NO == g_is_usb_bulk_writing) {
			ctrl.type = USB_PCDC;
			err = R_USB_Write(&ctrl, usb_message, 32);
			if (USB_SUCCESS == err) {
				g_is_usb_bulk_writing = USB_YES;
			}
		}

		/* SCI Error -> USB Notification */
		if (USB_NO == g_is_usb_interrupt_writing) {
			/* Check whether the SerialState information is or not*/
			if (0 != g_is_serial_state) {
				/* Send the SerialState information for SCI to USB Host */
				ctrl.type = USB_PCDCC;
				err = R_USB_Write(&ctrl, (uint8_t*) &g_serial_state, 2);
				if (USB_SUCCESS == err) {
					g_is_usb_interrupt_writing = USB_YES;
					g_is_serial_state = 0;
				}
			}
		}
		break;

	default:
		break;
	}
}

static void apl_init(void) {
	memset((void* )&g_line_coding, 0, sizeof(usb_pcdc_linecoding_t));
	memset(g_usb_data, 0, DATA_LEN);
	memset(g_sci_data, 0, DATA_LEN);
	memset(g_serial_state, 0, 2);
	memset(console, 0, sizeof(sci_hdl_t));
	g_is_usb_bulk_writing = USB_NO;
	g_is_usb_interrupt_writing = USB_NO;
	g_is_serial_state = 0;

} /* End of function apl_init */

static void usb_pin_setting(void) {
#if USE_USBIP == USB_IP0
	R_USB_PinSet_USB0_PERI();
#else   /* USE_USBIP == USE_USBIP0 */
    R_USB_PinSet_USB1_PERI();
#endif  /* USE_USBIP == USE_USBIP0 */
} /* End of function usb_pin_setting */

#endif  /* OPERATION_MODE == USB_UART */
```

### 使い方
　mainプログラムからは，次のように使う．
　この例では，ADCのデータをUSB経由で順次PCに送っている．

```main.c
#include "r_usb_basic_if.h"
#include "stdio.h"
#include "r_usb_pcdc_apl.h"

uint16_t ADValue;
extern uint8_t usb_message[32];  //表示したいメッセージを設定する

void initAD(){
	MSTP(AD0) = 0;
	AD0.ADCSR.BIT.CH = 0x01;
	AD0.ADCR.BIT.MODE = 0x00;
	AD0.ADCR.BIT.CKS = 0x03;
	AD0.ADDPR.BIT.DPSEL = 0;  //LSB
}

void main (void)
{
	PORT1.DDR.BIT.B5 = 1;  //On Board LED
	PORT1.DR.BIT.B5 = 0;

	initAD();
	usb_init();  //初期化

	while(1){
		for(int i=0; i<5000000; i++);
		usb_loop();  //定期的に呼ぶ

        /* ADC */
            AD0.ADCSR.BIT.ADST = 1;
            for(int i=0; i<100; i++);
            for(; AD0.ADCSR.BIT.ADST;)  /* wait adc complete */
            	for(int i=0; i<100; i++);
            ADValue = AD0.ADDRB;  /* valid AN0 MSB8 */
        	snprintf(usb_message, 16, " Value: %d \r\n", ADValue);
	}
}
```



# ハードウェアの初期化
　動作クロックなどをデフォルトの設定から変えたい場合は，
　generate/hwinit.c の HardwareSetup()に書く．

```hwinit.c
:
void HardwareSetup(void)
{
	SYSTEM.SCKCR.LONG = 0x00C10100;  //システムクロックなどの設定
/*
  SCI.SMR.BYTE = 0;
  SCI.SMR.BIT.CA   = 1;
:
*/
}
```



# 参考サイト
（0）ユーザ―マニュアル
https://www.renesas.com/jp/ja/document/mah/rx62n-group-rx621-group-users-manual-hardware-rev140?language=ja&r=1054421
（1）データシート
https://www.renesas.com/us/en/document/dst/rx62nrx621-group-datasheet-rev140
（2）ビルドと書き込み
https://setoti.hatenablog.com/entry/rx_write
（3）
https://www.haljion.net/index.php/2019-11-13-03-27-18/119-2019-11-13-03-22-16/rx-62n/226-2019-11-18-00-17-25
（4）山本ワールド；LCDモジュール(SC1602) 4bitモードライブラリー
http://yamatyuu.net/computer/pic/usbio2/lcdc_lib1/index.html
（5）忘備録-備忘録
https://blog.goo.ne.jp/lm324/e/99f735aef942ce6b965cd2f985acdf73
（6）
https://www.elec-hobbyist.com/MicomMemo/RX62_Micom/RX62_Explana_2.html
（7）ソフトウェア開発日記，C言語で文字列・数値変換を行う方法
https://lightgauge.net/language/c-language/6946/