I am working on interfacing the MAX5144 DAC using SPI communication on a Raspberry Pi (SPI1, CS1). Below is my main program and my SPI testing program.
The main program initializes the DAC and sets the output value, but I encounter the following error:
wiringPiSPI: Invalid SPI number/channel (need wiringPiSPIxSetupMode before read/write)
The SPI test program runs successfully, confirming that SPI1 and CS1 are correctly set up.
cmake_minimum_required(VERSION 3.10)
project(TemperatureControlProject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "-g")
# Add custom module path for FindWiringPi.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include_directories(include)
# Main project executable
add_executable(TemperatureControlProject src/main.cpp src/MAX5144.cpp)
find_package(WiringPi REQUIRED)
target_link_libraries(TemperatureControlProject ${WIRINGPI_LIBRARY})
# SPI test executable
add_executable(SPITest src/spi_test.cpp)
target_link_libraries(SPITest -lwiringPi)
#include "MAX5144.h"
#include <iostream>
int main() {
try {
MAX5144 dac(1, 17); // SPI channel 1, CS pin GPIO17
dac.setDacOutput(4854); // Set DAC output value
std::cout << "DAC output successfully set." << std::endl;
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
#include "MAX5144.h"
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <iostream>
#include <stdexcept>
MAX5144::MAX5144(int spiChannel, int csPin) : csPin(csPin) {
wiringPiSetup();
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH);
if (wiringPiSPISetupMode(spiChannel, 500000, 0) < 0) {
throw std::runtime_error("SPI initialization failed!");
}
}
void MAX5144::setDacOutput(int value) {
if (value < 0 || value >= 16384) {
throw std::invalid_argument("DAC value out of range!");
}
int dataWord = value << 2;
unsigned char msb = (dataWord >> 8) & 0xFF;
unsigned char lsb = dataWord & 0xFF;
digitalWrite(csPin, LOW);
unsigned char buffer[2] = {msb, lsb};
wiringPiSPIDataRW(1, buffer, 2); // SPI channel 1
digitalWrite(csPin, HIGH);
std::cout << "DAC output set to: " << value << std::endl;
}
MAX5144::~MAX5144() {}
#include <wiringPiSPI.h>
#include <iostream>
#include <stdexcept>
int main() {
int spiChannel = 1; // Using SPI1
int speed = 500000; // SPI speed
int mode = 0; // SPI mode 0
if (wiringPiSPISetupMode(spiChannel, speed, mode) < 0) {
throw std::runtime_error("SPI1 initialization failed!");
}
std::cout << "SPI1 initialized successfully!" << std::endl;
unsigned char buffer[2] = {0xFF, 0x00}; // Test data
if (wiringPiSPIDataRW(spiChannel, buffer, 2) < 0) {
throw std::runtime_error("SPI1 data transfer failed!");
}
std::cout << "SPI1 data sent successfully!" << std::endl;
return 0;
}
Hardware Test Results: The DAC works perfectly when controlled using Python, so there are no hardware-related issues with the SPI setup or the MAX5144 IC.
Observed Error: The error in the main program suggests a problem with SPI channel initialization (wiringPiSPISetupMode), but the SPI test program verifies that SPI1 and CS1 are functioning as expected.
wiringPiSPIDataRW(1, ...)
in the MAX5144::setDacOutput
method correct for SPI1?#include "MAX5144.h"
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdexcept>
#include <iostream>
// Constructor
MAX5144::MAX5144(int spiNumber, int spiChannel, int csPin, int speed, int mode)
: spiNumber(spiNumber), spiChannel(spiChannel), csPin(csPin) {
// Initialize GPIO for CS
if (wiringPiSetup() < 0) {
throw std::runtime_error("Failed to initialize WiringPi!");
}
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH); // Default to deselected state
// Initialize SPI
if (wiringPiSPIxSetupMode(spiNumber, spiChannel, speed, mode) < 0) {
throw std::runtime_error("SPI initialization failed for SPI" + std::to_string(spiNumber) +
", Channel " + std::to_string(spiChannel));
}
std::cout << "SPI initialized on SPI" << spiNumber << ", Channel " << spiChannel << std::endl;
}
// Set DAC Output
void MAX5144::setDacOutput(int value) {
if (value < 0 || value > 16383) {
throw std::invalid_argument("DAC value out of range! Must be between 0 and 16383.");
}
// Prepare data
int dataWord = value << 2; // Align 14-bit value
unsigned char buffer[2] = {
static_cast<unsigned char>((dataWord >> 8) & 0xFF), // MSB
static_cast<unsigned char>(dataWord & 0xFF) // LSB
};
// SPI Transfer
digitalWrite(csPin, LOW); // Select chip
if (wiringPiSPIxDataRW(spiNumber, spiChannel, buffer, 2) < 0) {
throw std::runtime_error("SPI data transfer failed!");
}
digitalWrite(csPin, HIGH); // Deselect chip
std::cout << "DAC output set to: " << value << std::endl;
}
// Destructor
MAX5144::~MAX5144() {
wiringPiSPIClose(spiChannel); // Close SPI channel
}
mic drop :)
welcome to visits my github https://github.com/dcl920108/MAX5144-SPI-Driver/blob/main/MAX5144.cpp