"Hello,RL78!"を送信後、受信した文字をエコーバックする動作を確認しました。
開発環境はe2studioを使っています。RL78/G1Eは対応していないのでG1Aでプロジェクトを作成して、CubeSuite+が吐いた定数定義、下のソースで言うと"_0010_SAU_STOP_1"を真似して使っています。これの意味は、0x0010 でシリアル通信の設定レジスタにビットOR演算で設定することで設定レジスタの該当ビットを操作して設定しています。ヘッダファイルの中で定義して使っています。送受信周りのイベントハンドラはinterrupt_handlers.c内にあるイベントハンドラから自分のソース側の対応関数をコールするように記述を追加しておきます。単体では参考にならないかもしれませんが、自分の備忘録も兼ねてソースを掲載します。現時点で、ボーレート設定とか連続受信の辺りがまだ動いていない可能性大です。
そういえば、なんのためにSmart Analog Stickでシリアル通信しようと思ってたんだっけ?なにか本来の目的の補助ツール(デバッグ出力)としてシリアル通信を用意しようと思ってたんだけど・・・、本題が何だったかな?
/***********************************************************************/
/* */
/* PROJECT NAME : RL78UARTTest */
/* FILE : RL78UARTTest.cpp */
/* DESCRIPTION : Main Program */
/* CPU SERIES : RL78 - G1A */
/* CPU TYPE : R5F10ELE */
/* */
/* This file is generated by e2studio. */
/* */
/***********************************************************************/
#include "iodefine.h"
#include "iodefine_ext.h"
#include "typedefine.h"
#include "rl78_serial.h"
#ifdef CPPAPP
//Initialize global constructors
extern "C" void __main()
{
static int initialized;
if (! initialized)
{
typedef void (*pfunc) ();
extern pfunc __ctors[];
extern pfunc __ctors_end[];
pfunc *p;
initialized = 1;
for (p = __ctors_end; p > __ctors; )
(*--p) ();
}
}
#endif
// マクロ定義。
// 定数define定義。
#define UART_TX_BUF_SIZE (64U)
#define UART_RX_BUF_SIZE (64U)
// グローバル変数宣言。
volatile uint8_t g_tx0_buffer[UART_TX_BUF_SIZE];
volatile uint16_t g_tx0_in_index;
volatile uint16_t g_tx0_out_index;
volatile uint8_t g_rx0_buffer[UART_RX_BUF_SIZE];
volatile uint16_t g_rx0_in_index;
volatile uint16_t g_rx0_out_index;
volatile uint8_t g_tx2_buffer[UART_TX_BUF_SIZE];
volatile uint16_t g_tx2_in_index;
volatile uint16_t g_tx2_out_index;
volatile uint8_t g_rx2_buffer[UART_RX_BUF_SIZE];
volatile uint16_t g_rx2_in_index;
volatile uint16_t g_rx2_out_index;
// 関数プロトタイプ宣言。
void setup(void);
void loop(void);
void UART0_begin(unsigned long baudrate);
void UART2_begin(unsigned long baudrate);
void UART0_write(uint8_t txData);
void UART2_write(uint8_t tcData);
uint16_t UART0_writes(uint8_t *str);
uint16_t UART2_writes(uint8_t *str);
uint8_t UART0_read(void);
uint8_t UART2_read(void);
uint16_t UART0_available(void);
uint16_t UART2_available(void);
// 割り込みイベントハンドラ。interrupt_handlers.c の
// 対応ハンドラ関数内でコールするように設定すること。
extern "C" void Handler_INT_ST0(void);
extern "C" void Handler_INT_ST2(void);
extern "C" void Handler_INT_SR0(void);
extern "C" void Handler_INT_SR2(void);
// HardwareSerial Class 定義。
class HardwareSerial
{
};
int main(void)
{
// 初期設定。
setup();
while(1) {
loop();
}
return 0;
}
void setup(void) {
// 割り込み禁止。
DI();
// シリアルポートの初期化。
//UART0_begin(9600);
UART2_begin(9600);
// 割り込み許可。
EI();
//UART0_write((uint8_t)'T');
//UART2_write((uint8_t)'t');
uint8_t msgHello[14] = {"Hello,RL78!\r\n"};
UART2_writes(msgHello);
}
void loop(void)
{
if (UART2_available() > 0) {
UART2_write(UART2_read());
}
}
void UART0_begin(unsigned long baudrate)
{
// グローバル変数初期化。
g_tx0_in_index = 0U;
g_tx0_out_index = 0U;
g_rx0_in_index = 0U;
g_rx0_out_index = 0U;
// ボーレート計算
uint16_t sdr_value = ((uint16_t)(2000000 / baudrate))&0xfe;
sdr_value = (sdr_value>>1) - 1;
sdr_value = (sdr_value<<9)&0xff00;
// --- SAU設定。SAU0-ch0,ch1をUART1のTx,Rxとして利用。
// SAU1をイネーブル。
SAU0EN = 1U;
// シリアル・クロック選択レジスタSPS0を設定。
SPS0.sps0 = _0004_SAU_CK00_FCLK_4 | _0040_SAU_CK01_FCLK_4;
// シリアルチャネル停止レジスタST0に停止トリガを書き込んで、送受信を停止。
ST0.st0 |= _0002_SAU_CH1_STOP_TRG_ON | _0001_SAU_CH0_STOP_TRG_ON;
// シリアル送信転送完了割り込み INTST0 禁止。
STMK0 = 1U;
// シリアル送信転送完了割り込み INTST0 フラグクリア。
STIF0 = 0U;
// シリアル受信転送完了割り込み INTSR0 禁止。
SRMK0 = 1U;
// シリアル受信転送完了割り込み INTSR0 フラグクリア。
SRIF0 = 0U;
// シリアル受信エラー割り込み INTSRE0 禁止。
SREMK0 = 1U;
// シリアル受信エラー割り込み INTSRE0 フラグクリア。
SREIF0 = 0;
// シリアル送信割り込み優先順位を低(3)に設定。
STPR00 = 1U;
STPR10 = 1U;
// シリアル受信割り込み優先順位を低(3)に設定。
SRPR00 = 1U;
SRPR10 = 1U;
// シリアルエラー割り込み優先順位を低(3)に設定。
SREPR00 = 1U;
SREPR10 = 1U;
// シリアルモードレジスタ SMR00 を設定。
SMR00.smr00 =
_0020_SAU_SMRMN_INITIALVALUE | // 初期値でBIT5=1U。
_0000_SAU_CLOCK_SELECT_CK00 | // クロックはSPS0レジスタで設定したCK00。
_0000_SAU_TRIGGER_SOFTWARE | // スタートトリガはソフトトリガのみ有効。(UART送信)
_0002_SAU_MODE_UART | // UARTモード。
_0000_SAU_TRANSFER_END; // 転送完了割り込みモード。
// シリアル通信動作設定レジスタ SCR00 を設定。
SCR00.scr00 =
_8000_SAU_TRANSMISSION | // 送信のみを行う。
_0000_SAU_INTSRE_MASK | // エラー割り込みマスク(INSTRE)する。
_0000_SAU_PARITY_NONE | // パリティなし。
_0080_SAU_LSB | // LSBファーストで入出力。
_0010_SAU_STOP_1 | // ストップビット長=1bit。
_0007_SAU_LENGTH_8; // データ長=8bit。
// シリアルデータレジスタ SDR00 (下位バイトが送受信バッファで、上位バイトが分周設定。)
SDR00.sdr00 = sdr_value;
// シリアルノイズフィルタ許可レジスタ NFEN0 を設定。
NFEN0.nfen0 |= _01_SAU_RXD0_FILTER_ON; // RXD0端子のノイズフィルタOn。
// シリアルフラグクリアトリガレジスタ SIR01 を設定。
SIR01.sir01 =
_0004_SAU_SIRMN_FECTMN | // SSR01のFEFビットを0クリア。
_0002_SAU_SIRMN_PECTMN | // SSR01のPEFビットを0クリア。
_0001_SAU_SIRMN_OVCTMN; // SSR01のOVFビットを0クリア。
// シリアルモードレジスタ SMR01 を設定。
SMR01.smr01 =
_0020_SAU_SMRMN_INITIALVALUE | // 初期値でBIT5=1U。
_0000_SAU_CLOCK_SELECT_CK00 | // クロックはSPS0レジスタで設定したCK00。
_0100_SAU_TRIGGER_RXD | // RxD端子の有効エッジ。(UART受信)
_0000_SAU_EDGE_FALL | // 立下りエッジをスタートビット、ビット反転なし。
_0002_SAU_MODE_UART | // UARTモード。
_0000_SAU_TRANSFER_END; // 転送完了割り込みモード。
// シリアル通信動作設定レジスタ SCR01 を設定。
SCR01.scr01 =
_4000_SAU_RECEPTION | // 受信のみを行う。
_0400_SAU_INTSRE_ENABLE | // エラー割り込み(INSTRE)発生を許可。
_0000_SAU_PARITY_NONE | // パリティなし。
_0080_SAU_LSB | // LSBファーストで入出力。
_0010_SAU_STOP_1 | // ストップビット長=1bit。
_0007_SAU_LENGTH_8; // データ長=8bit。
// シリアルデータレジスタ SDR01 (下位バイトが送受信バッファで、上位バイトが分周設定。)
SDR01.sdr01 = sdr_value;
// シリアル出力レジスタ SO0 設定。
SO0.so0 |= _0001_SAU_CH0_DATA_OUTPUT_1; // CH0シリアル出力"1"。
// シリアル出力レベルレジスタ SOL0 設定。
SOL0.sol0 |= _0000_SAU_CHANNEL0_NORMAL; // そのまま(レベル反転なし)で出力。
// シリアル出力許可レジスタ SOE0 設定。
SOE0.soe0 |= _0001_SAU_CH0_OUTPUT_ENABLE; // シリアル出力許可。
// --- 端子設定。
// P11 (UART0-RxD0) を入力端子に設定。
PMC1.BIT.bit1 = 0U;
PM1.BIT.bit1 = 1U;
// P12 (UART0-TxD0) を出力端子に設定。
PMC1.BIT.bit2 = 0U;
P1.BIT.bit2 = 1U;
PM1.BIT.bit2 = 0U;
// シリアル送信転送完了割り込み INTST0 フラグクリア。
STIF0 = 0U;
// シリアル送信転送完了割り込み INTST0 許可。
STMK0 = 0U;
// シリアル受信転送完了割り込み INTSR0 フラグクリア。
SRIF0 = 0U;
// シリアル受信転送完了割り込み INTSR0 許可。
SRMK0 = 0U;
// シリアル受信エラー割り込み INTSRE0 フラグクリア。
SREIF0 = 0;
// シリアル受信エラー割り込み INTSRE0 許可。
SREMK0 = 0U;
// シリアル出力レジスタ SO0 設定。
SO0.so0 |= _0001_SAU_CH0_DATA_OUTPUT_1; // CH0シリアル出力"1"。
// シリアル出力許可レジスタ SOE0 設定。
SOE0.soe0 |= _0001_SAU_CH0_OUTPUT_ENABLE; // シリアル出力許可。
// 送受信の開始。
SS0.ss0 |= _0001_SAU_CH0_START_TRG_ON |_0002_SAU_CH1_START_TRG_ON;
}
void UART2_begin(unsigned long baudrate)
{
// グローバル変数初期化。
g_tx2_in_index = 0U;
g_tx2_out_index = 0U;
g_rx2_in_index = 0U;
g_rx2_out_index = 0U;
// ボーレート計算
uint16_t sdr_value = ((uint16_t)(2000000 / baudrate))&0xfe;
sdr_value = (sdr_value>>1) - 1;
sdr_value = (sdr_value<<9)&0xff00;
// --- SAU設定。SAU1-ch0,ch1をUART1のTx,Rxとして利用。
// SAU1をイネーブル。
SAU1EN = 1U;
// シリアル・クロック選択レジスタSPS1を設定。
//SPS1.sps1 = _0002_SAU_CK00_FCLK_2 | _0090_SAU_CK01_FCLK_9;
SPS1.sps1 = _0004_SAU_CK00_FCLK_4 | _0040_SAU_CK01_FCLK_4;
// シリアルチャネル停止レジスタST1に停止トリガを書き込んで、送受信を停止。
ST1.st1 |= _0002_SAU_CH1_STOP_TRG_ON | _0001_SAU_CH0_STOP_TRG_ON;
// シリアル送信転送完了割り込み INTST2 禁止。
STMK2 = 1U;
// シリアル送信転送完了割り込み INTST2 フラグクリア。
STIF2 = 0U;
// シリアル受信転送完了割り込み INTSR2 禁止。
SRMK2 = 1U;
// シリアル受信転送完了割り込み INTSR2 フラグクリア。
SRIF2 = 0U;
// シリアル受信エラー割り込み INTSRE2 禁止。
SREMK2 = 1U;
// シリアル受信エラー割り込み INTSRE2 フラグクリア。
SREIF2 = 0U;
// シリアル送信割り込み優先順位を低(3)に設定。
STPR12 = 1U;
STPR02 = 1U;
// シリアル受信割り込み優先順位を低(3)に設定。
SRPR12 = 1U;
SRPR02 = 1U;
// シリアルエラー割り込み優先順位を低(3)に設定。
SREPR12 = 1U;
SREPR02 = 1U;
// シリアルモードレジスタ SMR10 を設定。
SMR10.smr10 =
_0020_SAU_SMRMN_INITIALVALUE | // 初期値でBIT5=1U。
_8000_SAU_CLOCK_SELECT_CK01 | // クロックはSPS1レジスタで設定したCK01。
_0000_SAU_TRIGGER_SOFTWARE | // スタートトリガはソフトトリガのみ有効。(UART送信)
_0002_SAU_MODE_UART | // UARTモード。
_0000_SAU_TRANSFER_END; // 転送完了割り込みモード。
// シリアル通信動作設定レジスタ SCR10 を設定。
SCR10.scr10 =
_8000_SAU_TRANSMISSION | // 送信のみを行う。
_0000_SAU_INTSRE_MASK | // エラー割り込みマスク(INSTRE)する。
_0000_SAU_PARITY_NONE | // パリティなし。
_0080_SAU_LSB | // LSBファーストで入出力。
_0010_SAU_STOP_1 | // ストップビット長=1bit。
_0007_SAU_LENGTH_8; // データ長=8bit。
// シリアルデータレジスタ SDR10 (下位バイトが送受信バッファで、上位バイトが分周設定。)
SDR10.sdr10 = sdr_value;
// シリアルノイズフィルタ許可レジスタ NFEN0 を設定。
NFEN0.nfen0 |= _01_SAU_RXD0_FILTER_ON; // RXD0端子のノイズフィルタOn。
// シリアルフラグクリアトリガレジスタ SIR11 を設定。
SIR11.sir11 =
_0004_SAU_SIRMN_FECTMN | // SSR11のFEFビットを0クリア。
_0002_SAU_SIRMN_PECTMN | // SSR11のPEFビットを0クリア。
_0001_SAU_SIRMN_OVCTMN; // SSR11のOVFビットを0クリア。
// シリアルモードレジスタ SMR11 を設定。
SMR11.smr11 =
_0020_SAU_SMRMN_INITIALVALUE | // 初期値でBIT5=1U。
_0000_SAU_CLOCK_SELECT_CK00 | // クロックはSPS0レジスタで設定したCK00。
_0100_SAU_TRIGGER_RXD | // RxD端子の有効エッジ。(UART受信)
_0000_SAU_EDGE_FALL | // 立下りエッジをスタートビット、ビット反転なし。
_0002_SAU_MODE_UART | // UARTモード。
_0000_SAU_TRANSFER_END; // 転送完了割り込みモード。
// シリアル通信動作設定レジスタ SCR11 を設定。
SCR11.scr11 =
_4000_SAU_RECEPTION | // 受信のみを行う。
_0400_SAU_INTSRE_ENABLE | // エラー割り込み(INSTRE)発生を許可。
_0000_SAU_PARITY_NONE | // パリティなし。
_0080_SAU_LSB | // LSBファーストで入出力。
_0010_SAU_STOP_1 | // ストップビット長=1bit。
_0007_SAU_LENGTH_8; // データ長=8bit。
// シリアルデータレジスタ SDR01 (下位バイトが送受信バッファで、上位バイトが分周設定。)
SDR11.sdr11 = sdr_value;
// シリアル出力レジスタ SO0 設定。
SO1.so1 |= _0001_SAU_CH0_DATA_OUTPUT_1; // CH0シリアル出力"1"。
// シリアル出力レベルレジスタ SOL0 設定。
SOL1.sol1 |= _0000_SAU_CHANNEL0_NORMAL; // そのまま(レベル反転なし)で出力。
// シリアル出力許可レジスタ SOE0 設定。
SOE1.soe1 |= _0001_SAU_CH0_OUTPUT_ENABLE; // シリアル出力許可。
// --- 端子設定。
// P14 (UART1-RxD2) を入力端子に設定。
PMC1.BIT.bit4 = 0U;
PM1.BIT.bit4 = 1U;
// P13 (UART1-TxD2) を出力端子に設定。
PMC1.BIT.bit3 = 0U;
P1.BIT.bit3 = 1U;
PM1.BIT.bit3 = 0U;
// シリアル送信転送完了割り込み INTST2 フラグクリア。
STIF2 = 0U;
// シリアル送信転送完了割り込み INTST2 許可。
STMK2 = 0U;
// シリアル受信転送完了割り込み INTSR2 フラグクリア。
SRIF2 = 0U;
// シリアル受信転送完了割り込み INTSR2 許可。
SRMK2 = 0U;
// シリアル受信エラー割り込み INTSRE2 フラグクリア。
SREIF2 = 0;
// シリアル受信エラー割り込み INTSRE2 許可。
SREMK2 = 0U;
// シリアル出力レジスタ SO0 設定。
SO1.so1 |= _0001_SAU_CH0_DATA_OUTPUT_1; // CH0シリアル出力"1"。
// シリアル出力許可レジスタ SOE0 設定。
SOE1.soe1 |= _0001_SAU_CH0_OUTPUT_ENABLE; // シリアル出力許可。
// 送受信の開始。
SS1.ss1 |= _0001_SAU_CH0_START_TRG_ON |_0002_SAU_CH1_START_TRG_ON;
}
void UART0_write(uint8_t txData)
{
if (SSR00.BIT.bit5 == 0) {
// バッファが空(SSRレジスタのBFFビット=0)なら、直接送信。
// INST0 割り込み禁止。
STMK0 = 1U;
// 送信データセット。
TXD0.txd0 = txData;
// INST0 割り込み許可。
STMK0 = 0U;
} else {
// バッファに書き込み。
g_tx0_buffer[g_tx0_in_index] = txData;
g_tx0_in_index++;
if (g_tx0_in_index >= UART_TX_BUF_SIZE) {
g_tx0_in_index = 0;
}
}
}
void UART2_write(uint8_t txData)
{
if (SSR10.BIT.bit5 == 0) {
// バッファが空(SSRレジスタのBFFビット=0)なら、直接送信。
// INST2 割り込み禁止。
STMK2 = 1U;
// 送信データセット。
TXD2.txd2 = txData;
// INST2 割り込み許可。
STMK2 = 0U;
} else {
// バッファに書き込み。
g_tx2_buffer[g_tx2_in_index] = txData;
g_tx2_in_index++;
if (g_tx2_in_index >= UART_TX_BUF_SIZE) {
g_tx2_in_index = 0;
}
}
}
uint16_t UART0_writes(uint8_t *str)
{
uint16_t i;
for (i = 0; i < 1000; i++) {
if (*(str + i) == '\0') break;
UART0_write(*(str + i));
}
return i;
}
uint16_t UART2_writes(uint8_t *str)
{
uint16_t i;
for (i = 0; i < 1000; i++) {
if (*(str + i) == '\0') break;
UART2_write(*(str + i));
}
return i;
}
uint8_t UART0_read(void)
{
uint8_t rxData;
while(UART0_available() == 0);
rxData = g_rx0_buffer[g_rx0_out_index];
g_rx0_out_index++;
if (g_rx0_out_index >= UART_RX_BUF_SIZE) {
g_rx0_out_index = 0;
}
return rxData;
}
uint8_t UART2_read(void)
{
uint8_t rxData;
while(UART2_available() == 0);
rxData = g_rx2_buffer[g_rx2_out_index];
g_rx2_out_index++;
if (g_rx2_out_index >= UART_RX_BUF_SIZE) {
g_rx2_out_index = 0;
}
return rxData;
}
uint16_t UART0_available(void)
{
uint16_t rcvCount = 0;
if (g_rx0_in_index == g_rx0_out_index) {
return 0;
} else {
if (g_rx0_in_index > g_rx0_out_index)
{
rcvCount = g_rx0_in_index - g_rx0_out_index;
} else {
rcvCount = UART_RX_BUF_SIZE - g_rx0_out_index;
rcvCount += g_rx0_in_index;
}
return rcvCount;
}
}
uint16_t UART2_available(void)
{
uint16_t rcvCount = 0;
if (g_rx2_in_index == g_rx2_out_index) {
return 0;
} else {
if (g_rx2_in_index > g_rx2_out_index)
{
rcvCount = g_rx2_in_index - g_rx2_out_index;
} else {
rcvCount = UART_RX_BUF_SIZE - g_rx2_out_index;
rcvCount += g_rx2_in_index;
}
return rcvCount;
}
}
void Handler_INT_ST0(void)
{
// 送信レジスタが空になった時に、バッファにデータがあれば、
// 引き続き送信。
if (g_tx0_in_index == g_tx0_out_index) {
// バッファが空なら何もしない。
} else {
// バッファから送信。
// INST0 割り込み禁止。
STMK0 = 1U;
// 送信データセット。
TXD0.txd0 = g_tx0_buffer[g_tx0_out_index];
g_tx0_out_index++;
if (g_tx0_out_index >= UART_TX_BUF_SIZE) {
g_tx0_out_index = 0;
}
// INST2 割り込み許可。
STMK0 = 0U;
}
}
void Handler_INT_ST2(void)
{
// 送信レジスタが空になった時に、バッファにデータがあれば、
// 引き続き送信。
if (g_tx2_in_index == g_tx2_out_index) {
// バッファが空なら何もしない。
} else {
// バッファから送信。
// INST2 割り込み禁止。
STMK2 = 1U;
// 送信データセット。
TXD2.txd2 = g_tx2_buffer[g_tx2_out_index];
g_tx2_out_index++;
if (g_tx2_out_index >= UART_TX_BUF_SIZE) {
g_tx2_out_index = 0;
}
// INST2 割り込み許可。
STMK2 = 0U;
}
}
void Handler_INT_SR0(void)
{
// 受信完了でバッファに書き込み。
g_rx0_buffer[g_rx0_in_index] = RXD0.rxd0;
g_rx0_in_index++;
if (g_rx0_in_index >= UART_RX_BUF_SIZE) {
g_rx0_in_index = 0;
}
}
void Handler_INT_SR2(void)
{
// 受信完了でバッファに書き込み。
g_rx2_buffer[g_rx2_in_index] = RXD2.rxd2;
g_rx2_in_index++;
if (g_rx2_in_index >= UART_RX_BUF_SIZE) {
g_rx2_in_index = 0;
}
}


0 件のコメント:
コメントを投稿