From 048b239b926edfb1b92c253e65e9a1163099a81e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 18:01:28 +0100 Subject: [PATCH] spi bugfixes --- linux/boardtest/SpiTestClass.cpp | 89 +++++++++++++++++++++++++------- linux/boardtest/SpiTestClass.h | 8 +++ linux/spi/SpiComIF.cpp | 10 ++-- linux/utility/Utility.cpp | 2 +- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 1065a2f4..050f9f15 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -10,6 +10,7 @@ #include #include #include +#include SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId), @@ -28,7 +29,7 @@ ReturnValue_t SpiTestClass::performOneShotAction() { break; } case(TestModes::MGM_RM3100): { - performRm3100Test(); + performRm3100Test(mgm1Rm3100ChipSelect); break; } case(TestModes::GYRO_L3GD20H): { @@ -47,7 +48,7 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { acsInit(); /* Adapt accordingly */ - if(mgmId != mgm1Rm3100ChipSelect or mgmId != mgm3Rm3100ChipSelect) { + if(mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) { sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl; } gpioId_t currentGpioId = 0; @@ -58,15 +59,18 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { else { currentGpioId = gpioIds::MGM_3_RM3100_CS; } - uint32_t rm3100Speed = 3'900'000; - uint8_t rm3100whoAmIReg = 0b0000'1111; - int rm3100mode = SPI_MODE_3; + uint32_t rm3100speed = 3'900'000; + uint8_t rm3100revidReg = 0x36; + spi::SpiMode rm3100mode = spi::SpiMode::MODE_3; + //spiTransferStruct.speed_hz = rm3100Speed; #ifdef RASPBERRY_PI - std::string deviceName = "spidev0.0"; + std::string deviceName = "/dev/spidev0.0"; #else + std::string deviceName = "placeholder"; #endif int fileDescriptor = 0; + utility::UnixFileHelper fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface: "); if(fileHelper.getOpenResult()) { @@ -74,20 +78,11 @@ void SpiTestClass::performRm3100Test(uint8_t mgmId) { << std::endl; return; } + setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed); - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, rm3100mode); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); - } - - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, rm3100Speed); - if(retval != 0) { - utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); - } - - gpioIF->pullLow(currentGpioId); - - + uint8_t revId = readStmRegister(fileDescriptor, currentGpioId, rm3100revidReg, false); + sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId) << + std::endl; } void SpiTestClass::acsInit() { @@ -132,3 +127,59 @@ void SpiTestClass::acsInit() { gpioIF->addGpios(gpioCookie); } } + +void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, + bool autoIncrement) { + if(autoIncrement) { + reg |= STM_AUTO_INCR_MASK; + } + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = value; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::writeStmRegister: Write failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } +} + +void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed) { + int retval = ioctl(spiFd, SPI_IOC_WR_MODE, reinterpret_cast(&mode)); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!"); + } + + retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if(retval != 0) { + utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!"); + } +} + +uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, + bool autoIncrement) { + reg |= STM_READ_MASK; + if(autoIncrement) { + reg |= STM_AUTO_INCR_MASK; + } + spiTransferStruct.len = 2; + sendBuffer[0] = reg; + sendBuffer[1] = 0; + + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullLow(chipSelect); + } + int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct); + if(retval < 0) { + utility::handleIoctlError("SpiTestClass::readStmRegiste: Read failed"); + } + if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) { + gpioIF->pullHigh(chipSelect); + } + return recvBuffer[1]; +} diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index 7a7c5f4c..c15a3fab 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -42,6 +42,14 @@ private: uint8_t mgm2Lis3mdlChipSelect = 17; uint8_t mgm3Rm3100ChipSelect = 27; + static constexpr uint8_t STM_READ_MASK = 0b1000'0000; + static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000; + + void setSpiSpeedAndMode(int spiFd, spi::SpiMode mode, uint32_t speed); + void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value, + bool autoIncrement); + uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement); + }; diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 7d5a5848..b656ac2d 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -88,12 +88,12 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return fileHelper.getOpenResult(); } - int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, static_cast(spiMode)); + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, reinterpret_cast(&spiMode)); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); } - retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, spiSpeed); + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI speed failed!"); } @@ -117,19 +117,19 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { currentMode |= SPI_CS_HIGH; } /* Write adapted mode */ - retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, currentMode); + retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, ¤tMode); if(retval != 0) { utility::handleIoctlError("SpiComIF::initialiezInterface: Could not write full mode!"); } } if(params.lsbFirst) { - retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, true); + retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, ¶ms.lsbFirst); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: Setting LSB first failed"); } } if(params.bitsPerWord != 8) { - retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, params.bitsPerWord); + retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, ¶ms.bitsPerWord); if(retval != 0) { utility::handleIoctlError("SpiComIF::initializeInterface: " "Could not write bits per word!"); diff --git a/linux/utility/Utility.cpp b/linux/utility/Utility.cpp index 8f1ca912..45c347db 100644 --- a/linux/utility/Utility.cpp +++ b/linux/utility/Utility.cpp @@ -20,7 +20,7 @@ void utility::handleIoctlError(const char* const customPrintout) { utility::UnixFileHelper::UnixFileHelper(std::string device, int* fileDescriptor, int flags, std::string diagnosticPrefix): - fileDescriptor(fileDescriptor) { + fileDescriptor(fileDescriptor) { if(fileDescriptor == nullptr) { return; }