📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
細 文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag… |
|||
| (同じ利用者による、間の5版が非表示) | |||
| 68行目: | 68行目: | ||
*: 各ワード転送後にCSをトグルするかどうかを指定する。 | *: 各ワード転送後にCSをトグルするかどうかを指定する。 | ||
*: 通常、CSはトランザクション全体で低いままであるが、一部のデバイスでは各ワード間でCSをトグルする必要がある。 | *: 通常、CSはトランザクション全体で低いままであるが、一部のデバイスでは各ワード間でCSをトグルする必要がある。 | ||
<br><br> | |||
== SPI通信の共通クラスの定義 == | |||
SPI通信の設定を以下に示す。<br> | |||
* LSB First | |||
* 3線式SPIモード / 4線式SPIモード | |||
* ループバックモード | |||
* No Chip Select (CS) | |||
* Ready | |||
* CS Change | |||
<br> | |||
<u>※注意</u><br> | |||
<u>一部のSPIデバイスやドライバでは、これらの設定の一部がサポートされていない場合がある。</u><br> | |||
<u>使用する前に、ターゲットのハードウェアとドライバがこれらの設定をサポートしていることを確認すること。</u><br> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// SpiDevice.hファイル | |||
#include <QObject> | |||
#include <QFile> | |||
#include <QFuture> | |||
#include <QtConcurrent> | |||
#include <sys/ioctl.h> | |||
#include <linux/spi/spidev.h> | |||
#include <fcntl.h> | |||
#include <unistd.h> | |||
class SpiDevice : public QObject | |||
{ | |||
Q_OBJECT | |||
protected: | |||
QString m_devicePath; | |||
public: | |||
enum class Mode { | |||
Mode0 = SPI_MODE_0, | |||
Mode1 = SPI_MODE_1, | |||
Mode2 = SPI_MODE_2, | |||
Mode3 = SPI_MODE_3 | |||
}; | |||
struct Config { | |||
Mode mode = Mode::Mode0; | |||
bool lsbFirst = false; | |||
bool threeWire = false; | |||
bool loopback = false; | |||
bool noCs = false; | |||
bool ready = false; | |||
bool csChange = false; | |||
uint8_t bitsPerWord = 8; | |||
uint32_t speed = 500000; | |||
}; | |||
explicit SpiDevice(const QString& devicePath, QObject* parent = nullptr) : QObject(parent), m_devicePath(devicePath) | |||
{} | |||
bool configure(const Config& config) | |||
{ | |||
QFile spiDevice(m_devicePath); | |||
if (!spiDevice.open(QIODevice::ReadWrite)) { | |||
emit errorOccurred("SPIデバイスを開けませんでした: " + spiDevice.errorString()); | |||
return false; | |||
} | |||
int fd = spiDevice.handle(); | |||
uint8_t mode = static_cast<uint8_t>(config.mode); | |||
if (config.lsbFirst) mode |= SPI_LSB_FIRST; | |||
if (config.threeWire) mode |= SPI_3WIRE; | |||
if (config.loopback) mode |= SPI_LOOP; | |||
if (config.noCs) mode |= SPI_NO_CS; | |||
if (config.ready) mode |= SPI_READY; | |||
if (config.csChange) mode |= SPI_CS_HIGH; | |||
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0 || ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &config.bitsPerWord) < 0 || | |||
ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &config.speed) < 0) { | |||
emit errorOccurred("SPIの設定に失敗しました"); | |||
spiDevice.close(); | |||
return false; | |||
} | |||
spiDevice.close(); | |||
return true; | |||
} | |||
signals: | |||
void errorOccurred(const QString& error); | |||
}; | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
| 84行目: | 173行目: | ||
#include <fcntl.h> | #include <fcntl.h> | ||
#include <unistd.h> | #include <unistd.h> | ||
#include "SpiDevice.h" | |||
class SpiReader : public | class SpiReader : public SpiDevice | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
private: | private: | ||
std::atomic<bool> m_stopReading{false}; | std::atomic<bool> m_stopReading{false}; | ||
public: | public: | ||
using SpiDevice::SpiDevice; | |||
void startReading(int bufferSize = 1024) | void startReading(int bufferSize = 1024) | ||
| 107行目: | 195行目: | ||
int fd = spiDevice.handle(); | int fd = spiDevice.handle(); | ||
QByteArray buffer(bufferSize, 0); | QByteArray buffer(bufferSize, 0); | ||
while (!m_stopReading) { | while (!m_stopReading) { | ||
| 142行目: | 219行目: | ||
signals: | signals: | ||
void dataRead(const QByteArray& data); | void dataRead(const QByteArray& data); | ||
void readingFinished(); | void readingFinished(); | ||
}; | }; | ||
| 159行目: | 235行目: | ||
SpiReader reader("/dev/spidev0.0"); | SpiReader reader("/dev/spidev0.0"); | ||
SpiDevice::Config config; | |||
config.mode = SpiDevice::Mode::Mode0; | |||
config.lsbFirst = true; | |||
config.threeWire = true; | |||
config.loopback = false; | |||
config.noCs = true; | |||
config.ready = false; | |||
config.csChange = false; | |||
config.bitsPerWord = 8; | |||
config.speed = 1000000; | |||
if (!reader.configure(config) || !writer.configure(config)) { | |||
qDebug() << "SPIデバイスの設定に失敗"; | |||
return -1; | |||
} | |||
QObject::connect(&reader, &SpiReader::dataRead, [](const QByteArray& data) { | QObject::connect(&reader, &SpiReader::dataRead, [](const QByteArray& data) { | ||
| 180行目: | 272行目: | ||
<br><br> | <br><br> | ||
== | == SPI通信の送信 == | ||
以下の例では、非同期処理を使用して、SPI通信でデータを送信している。<br> | 以下の例では、非同期処理を使用して、SPI通信でデータを送信している。<br> | ||
<br> | <br> | ||
| 186行目: | 278行目: | ||
// SpiWriter.hファイル | // SpiWriter.hファイル | ||
class SpiWriter : public SpiDevice | |||
class SpiWriter : public | |||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
using SpiDevice::SpiDevice; | |||
void writeData(const QByteArray& data) | void writeData(const QByteArray& data) | ||
| 213行目: | 295行目: | ||
int fd = spiDevice.handle(); | int fd = spiDevice.handle(); | ||
ssize_t ret = write(fd, data.constData(), data.size()); | ssize_t ret = write(fd, data.constData(), data.size()); | ||
if (ret < 0) { | if (ret < 0) { | ||
| 239行目: | 309行目: | ||
signals: | signals: | ||
void dataWritten(int bytes); | void dataWritten(int bytes); | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 248行目: | 317行目: | ||
#include <QCoreApplication> | #include <QCoreApplication> | ||
#include <QTimer> | #include <QTimer> | ||
#include " | #include "SpiDevice.h" | ||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||
| 255行目: | 324行目: | ||
SpiWriter writer("/dev/spidev0.0"); | SpiWriter writer("/dev/spidev0.0"); | ||
SpiDevice::Config config; | |||
config.mode = SpiDevice::Mode::Mode0; | |||
config.lsbFirst = true; | |||
config.threeWire = true; | |||
config.loopback = false; | |||
config.noCs = true; | |||
config.ready = false; | |||
config.csChange = false; | |||
config.bitsPerWord = 8; | |||
config.speed = 1000000; | |||
QObject::connect(&writer, &SpiWriter::dataWritten, [](int bytes) { | QObject::connect(&writer, &SpiWriter::dataWritten, [](int bytes) { | ||
| 263行目: | 343行目: | ||
qDebug() << "エラーが発生: " << error; | qDebug() << "エラーが発生: " << error; | ||
}); | }); | ||
QTimer::singleShot(5000, [&writer]() { | QTimer::singleShot(5000, [&writer]() { | ||
writer.writeData(QByteArray::fromHex("0102030405")); | writer.writeData(QByteArray::fromHex("0102030405")); | ||
| 273行目: | 353行目: | ||
<br><br> | <br><br> | ||
{{#seo: | |||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 | |||
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | |||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |||
}} | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] | ||