1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++でraspberry pi pico UARTを動かす

Posted at

記事を書くきっかけ

C言語でUARTの受信バッファやリングポインタ等をグローバル変数ベタで書いてみたのですが、どうにもしっくりこなくて、C++のクラスでまとまるか試してみました。

コード

2つのUART間で送受信を転送する簡単なプログラム例です。picowで動きました。
受信バッファのオーバーランは考慮していません。実験目的なのでご容赦ください。

uart.h
#ifndef _CUART_H
#define _CUART_H

/*
 * クラスの定義
 */
template <int CH, int RX_BUF_SIZE>
class CUart
{
protected:
	static CUart<CH, RX_BUF_SIZE>* _this;
	volatile uint16_t wp;
	uint16_t rp;
	uint8_t rx_buffer[RX_BUF_SIZE];

protected:
	void on_recv()
	{
		auto uart_inst = (CH == 0) ? uart0 : uart1;

		auto wp_tmp = this->wp;
		while ( ::uart_is_readable( uart_inst )) {
			const char c = uart_getc( uart_inst );
			this->rx_buffer[wp_tmp] = c;
			wp_tmp++;
			wp_tmp %= RX_BUF_SIZE ;
		}
		this->wp = wp1;
	}

	static void callback_on_recv()
	{
		_this->on_recv();
	}

public:
	inline void init( const uint baudrate, const uint8_t txPin, const uint8_t rxPin );
	inline void write( const char c ) const;
	inline void writes( const char text[] ) const;
	inline bool isReadable( void ) const;
	inline char read( void );
};

/*
 * 初期化
 */
template <int CH, int RX_BUF_SIZE>
inline void CUart<CH, RX_BUF_SIZE>::init( const uint baudrate, const uint8_t txPin, const uint8_t rxPin )
{
	this->_this = this;

	auto uart_inst = (CH == 0) ? uart0 : uart1;
	auto num = (CH == 0) ? UART0_IRQ : UART1_IRQ;

	uart_init( uart_inst, baudrate );
	uart_set_fifo_enabled( uart_inst, false );
	irq_set_exclusive_handler(num, callback_on_recv );
	uart_set_irq_enables( uart_inst, true, false );
	irq_set_enabled(UART0_IRQ, true);

    gpio_set_function( txPin, GPIO_FUNC_UART );
    gpio_set_function( rxPin, GPIO_FUNC_UART );
	uart_set_translate_crlf( uart_inst, false );
}

/*
 * 1文字送信
 */
template <int CH, int RX_BUF_SIZE>
inline void CUart<CH, RX_BUF_SIZE>::write( const char c ) const
{
	auto uart_inst = (CH == 0) ? uart0 : uart1;
	::uart_putc_raw(uart_inst, c);
}

/*
 * 文字列送信
 */
template <int CH, int RX_BUF_SIZE>
inline void CUart<CH, RX_BUF_SIZE>::writes( const char text[] ) const
{
	auto uart_inst = (CH == 0) ? uart0 : uart1;
	::uart_puts( uart_inst, text );
}

/*
 * 受信有無検査
 */
template <int CH, int RX_BUF_SIZE>
inline bool CUart<CH, RX_BUF_SIZE>::isReadable( void ) const
{
	return this->wp != this->rp ? true : false;
}

/*
 * 1文字受信
 */
template <int CH, int RX_BUF_SIZE>
inline char CUart<CH, RX_BUF_SIZE>::read( void )
{
	const char c = this->rx_buffer[this->rp];
	this->rp++;
	this->rp %= RX_BUF_SIZE ;
	return c;
}

using CUart0 = CUart<0, 8192>;
using CUart1 = CUart<1, 8192>;

extern CUart0 picoUart0;
extern CUart1 picoUart1;

#endif /* _CUART_H */
uart0.cpp

#include "uart.h"
CUart0 picoUart0;
template<> CUart0* CUart0::_this {};
uart1.cpp
#include "uart.h"

CUart1 picoUart1;
template<> CUart1* CUart1::_this {};
sample_main.cpp
#include "uart.h"

int main()
{
    {
        //115200bps
    	const uint baudrate = (115200);
        //GP0を送信に使用
    	const uint8_t txPin = (0);
        //GP1を受信に使用
    	const uint8_t rxPin = (1);
    	picoUart0.init( baudrate, txPin, rxPin );
    }

    {
        //115200bps
        const uint baudrate = (115200);
        //GP4を送信に使用
        const uint8_t txPin = (4);
        //GP5を受信に使用
    	const uint8_t rxPin = (5);
    	picoUart1.init( baudrate, txPin, rxPin );
    }

	while ( true ) {
        //チャンネル0の受信をチャンネル1に転送
        while ( picoUart0.isReadable() == true ) {
            const char c = picoUart0.read();
            picoUart1.write( c );
        }

        //チャンネル1の受信をチャンネル0に転送
        while ( picoUart1.isReadable() == true ) {
            const char c = picoUart1.read();
            picoUart0.write( c );
        }
    }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?