Beispiel #1
0
int mpu_spi_get_reg(int fd, int reg, uint8_t* val)
{
   int retVal;
   struct dspal_spi_ioctl_read_write read_write;


   retVal = mpu_spi_configure_speed(fd, MPU_SPI_FREQUENCY_1MHZ);
   if (retVal != 0)
   {
      LOG_ERR("mpu_spi_get_reg: error configuring speed %d", retVal);
      return retVal;
   }

   spiTxBuf[0] = reg | 0x80; //register high bit=1 for read

   read_write.read_buffer = spiRxBuf;
   read_write.read_buffer_length = 2;
   read_write.write_buffer = spiTxBuf;
   read_write.write_buffer_length = 2;
   retVal = ioctl(fd, SPI_IOCTL_RDWR, &read_write);
   if (retVal != 2)
   {
      FARF(ALWAYS, "mpu_spi_get_reg error read/write ioctl: %d", retVal);
      return retVal;
   }

   *val = spiRxBuf[1];

   FARF(LOW, "mpu_spi_get_reg %d=%d", reg, *val);

   return 0;
}
Beispiel #2
0
/**
* @brief Test to see if ioctl fails (ioctl is not supported for files)
*
* @par
* Test:
* 1) Opens file with dspal path prefix ('/dev/fs/test.txt') in read/write mode with append
* 2) Try ioctl call and make sure it fails
* 3) Close the file
*
* @return
* TEST_PASS ------ Always
*/
int dspal_tester_test_posix_file_ioctl(void)
{
   int fd;

   FARF(MEDIUM, "%s test", __FUNCTION__);

   fd = open(TEST_FILE_PATH, O_RDWR|O_TRUNC|O_TRUNC);
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_TRUNC|O_TRUNC mode");

   if (fd == -1)
   {
      FAIL("open test.txt failed. Make sure to have test.txt at $ADSP_LIBRARY_PATH");
   }

   FARF(MEDIUM, "trying ioctl()");
   if (ioctl(fd, 0, NULL) != -1)
   {
      FAIL("ioctl() is not supported and should have returned -1.");
   }

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   return TEST_PASS;
}
Beispiel #3
0
/**
* @brief Test file open/close operation
*
* @par Detailed Description:
* This tests opens a file from the adsp side ('/dev/fs/test.txt').  It then
* tries to open the file without the dspal file prefix ('test.txt').

* Test:
* 1) Opens file with dspal path prefix ('/dev/fs/test.txt') in O_RDWR mode
* 2) Close that file
* 3) Open file without dispal path prefix ('test.txt') in O_RDONLY mode
* 4) Close that file
*
* @return
* TEST_PASS ------ on success
* TEST_FAIL ------ on error
*/
int dspal_tester_test_posix_file_open_close(void)
{
   int fd;

   FARF(MEDIUM, "%s test", __FUNCTION__);

   // Open TEST_FILE_PATH.  Create the file if it doesn't exist.
   fd = open(TEST_FILE_PATH, O_RDWR|O_CREAT|O_TRUNC);
   if (fd == -1)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode. "
           "Make sure to have test.txt at $ADSP_LIBRARY_PATH");
   }
   FARF(MEDIUM, "open /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode");

   if (close(fd) != 0)
   {
      FAIL("failed to close file handle");
   }
   FARF(MEDIUM, "close /dev/fs/test.txt");

   // test open file path without dspal file path prefix
   fd = open("test.txt", O_RDONLY);
   // open() is expected to fail
   if (fd >= 0)
   {
      close(fd);
      FAIL("open() succ for invalid path test.txt. This should never happen!");
   }

   return TEST_PASS;
}
Beispiel #4
0
/**
* @brief Test to a file can be opened in all supported modes and closed.
*
* @par
* Test:
* 1) Opens file with dspal path prefix ('/dev/fs/test.txt') in one of the
*    fopen supported modes
* 2) Close the file
*
* @return
* TEST_FAIL ------ if fopen failed on certain mode
* TEST_PASS ------ if fopen succeeds on all modes
*/
int dspal_tester_test_fopen_fclose(void)
{
   FILE *fd;
   const char *modes[] = {
      "w", "w+", "r", "r+", "a", "a+"
   };
   int num_modes = sizeof(modes) / sizeof(const char *);

   FARF(MEDIUM, "%s test", __FUNCTION__);

   for (int i = 0; i < num_modes; i++)
   {
      fd = fopen(TEST_FILE_PATH, modes[i]);
      if (fd == NULL)
      {
         FARF(MEDIUM, "fopen() mode %s returned NULL", modes[i]);
         return TEST_FAIL;
      }
      fclose(fd);
      FARF(MEDIUM, "fopen()/fclose mode %s succ", modes[i]);
   }

   FARF(MEDIUM, "fopen_fclose test passed");

   return TEST_PASS;
}
Beispiel #5
0
/**
 * @brief Helper function  for 'dspal_tester_spi_test', checks if 2 data buffers are equal.
 *
 *
 * @param buffer1[in]  pointer to first buffer
 * @param buffer2[in]  pointer to second buffer
 * @param length[in]   length of each buffers
 *
 * @return
 * true  ------ data buffers match
 * false ------ data buffers do not match
*/
bool dpsal_tester_is_memory_matching(uint8_t *buffer1, uint8_t *buffer2, int length)
{
    if (memcmp(buffer1, buffer2, length) != 0) {
        FARF(ALWAYS, "error: the bytes read to not match the bytes written");
        FARF(ALWAYS, "bytes read: %c, %c, %c, %c, %c", buffer1[0], buffer1[1], buffer1[2],
             buffer1[3], buffer1[4]);
        FARF(ALWAYS, "bytes written: %c, %c, %c, %c, %c", buffer2[0], buffer2[1], buffer2[2],
             buffer2[3], buffer2[4]);
        return false;
    }

    return true;
}
Beispiel #6
0
/**
* @brief Test to a file can be written and read using fwrite() and frea()
*
* @par
* Test:
* 1) Opens file with dspal path prefix ('/dev/fs/test.txt') in write mode
* 2) write timestamp to file
* 3) fflush and fclose the file
* 4) open the file in r mode
* 5) fread() the file content and compare the bytes read and bytes written
* 6) Close the file
*
* @return
* TEST_PASS ------ if fwrite and fread succeed, and the bytes read and bytes
*                  written are identical.
* TEST_FAIL ------ otherwise
*/
int dspal_tester_test_fwrite_fread(void)
{
   FILE *fd;
   char buffer[50] = {0};
   uint64_t timestamp = time(NULL);
   size_t bytes_written;
   size_t bytes_read;
   size_t buffer_len;

   FARF(MEDIUM, "%s test", __FUNCTION__);

   fd = fopen(TEST_FILE_PATH, "w");
   if (fd == NULL)
   {
      FARF(MEDIUM, "fopen() mode w returned NULL");
      return TEST_FAIL;
   }

   sprintf(buffer, "test - timestamp: %llu\n", timestamp);
   buffer_len = strlen(buffer) + 1;

   FARF(MEDIUM, "writing to test.txt: %s (len: %d)", buffer, buffer_len);

   bytes_written = fwrite(buffer, 1, buffer_len, fd);
   if (bytes_written != buffer_len)
   {
      FARF(MEDIUM, "fwrite() %d bytes returned less than expected %d",
           buffer_len, bytes_written);
      return TEST_FAIL;
   }

   fflush(fd);
   fclose(fd);

   fd = fopen(TEST_FILE_PATH, "r");
   if (fd == NULL)
   {
      FARF(MEDIUM, "fopen() mode r returned NULL");
      return TEST_FAIL;
   }

   memset(buffer, 0, 50);
   bytes_read = fread(buffer, 1, buffer_len, fd);
   if (bytes_read != buffer_len)
   {
      FARF(MEDIUM, "fread() %d bytes returned less than expected %d",
           buffer_len, bytes_read);
      return TEST_FAIL;
   }

   FARF(MEDIUM, "fread() %d bytes: %s", bytes_read, buffer);

   fclose(fd);

   FARF(MEDIUM, "fwrite_fread test passed");

   return TEST_PASS;
}
Beispiel #7
0
/**
* @brief Test to remove the specified file
*
* @par
* Test:
* 1) Opens file with dspal path prefix ('/dev/fs/test.txt') and create it if
*    it does not exist
* 2) close the file
* 3) remove the file
*
* @return
* TEST_PASS ------ if remove returns 0
* TEST FAIL ------ on error
*/
int dspal_tester_test_posix_file_remove(void)
{
   int fd;

   FARF(MEDIUM, "%s test", __FUNCTION__);

   // First create the file if it does not exist yet
   fd = open(TEST_FILE_PATH, O_RDWR|O_CREAT);
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_CREAT mode");

   if (fd == -1)
   {
      FAIL("open test.txt failed. Make sure to have test.txt at $ADSP_LIBRARY_PATH");
   }

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   if (remove(TEST_FILE_PATH) != 0)
   {
      FARF(MEDIUM, "failed to remove %s", TEST_FILE_PATH);
      return TEST_FAIL;
   }
   FARF(MEDIUM, "removed /dev/fs/test.txt");

   // test removing a file with invalid dspal path
   if (remove("test.txt") == 0)
   {
      FARF(MEDIUM, "removed %s. This shouldn't happen", TEST_FILE_PATH);
      return TEST_FAIL;
   }
   FARF(MEDIUM, "removing file with invalid path failed. expected");

   return TEST_PASS;
}
Beispiel #8
0
/**
 * Main entry point for the SPI automated test.
 * @return
 * - ERROR: Indicates that the test has failed.
 * - SUCCESS: Test has passed
 */
int dspal_tester_spi_test(void)
{
    int result;

    FARF(ALWAYS, "beginning spi loopback test");

    if ((result = dspal_tester_spi_loopback_test()) < SUCCESS) {
        FARF(ALWAYS, "error: spi loopback test failed: %d", result);
        return result;
    }

    FARF(ALWAYS, "beginning spi exceed max write length test");

    if ((result = dspal_tester_spi_exceed_max_length_test()) < SUCCESS) {
        FARF(ALWAYS, "error: spi exceed max write length test failed: %d", result);
        return result;
    }

    return SUCCESS;
}
Beispiel #9
0
/**
 * @brief Test opening file in O_TRUNC mode
 *
 * @par
 * 1) open the file in O_WRONLY mode
 * 2) write timestamp to file
 * 3) close the file
 * 4) open the file in O_TRUNC mode
 * 5) read the file and verify if the file is empty
 * 6) cloes the file
 *
 * @return
 * TEST_PASS ------- file properly truncated
 * TEST_FAIL ------- on error
 */
int dspal_tester_test_posix_file_open_trunc()
{
   int fd;
   int bytes_read;
   char wbuf[100];
   char rbuf[100];
   uint64_t timestamp = time(NULL);

   FARF(MEDIUM, "%s test", __FUNCTION__);

   // Open the file in read/write mode
   fd = open(TEST_FILE_PATH, O_RDWR|O_CREAT|O_TRUNC);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode");

   // write timestamp
   memset(wbuf, 0, 100);
   sprintf(wbuf, "test - timestamp: %llu\n", timestamp);
   FARF(MEDIUM, "writing to %s: %s (len: %d)", TEST_FILE_PATH, wbuf,
       strlen(wbuf) + 1);

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   // open the file in O_TRUNC mode
   fd = open(TEST_FILE_PATH, O_RDWR|O_TRUNC);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_TRUNC mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_TRUNC mode");

   bytes_read = read(fd, rbuf, sizeof(rbuf)-1);
   FARF(MEDIUM, "read %d bytes from /dev/fs/test.txt", bytes_read);
   if (bytes_read != 0)
   {
      FAIL("Failed to truncate the file using O_TRUNC");
   }
   FARF(MEDIUM, "/dev/fs/test.txt in truncated");

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   return TEST_PASS;
}
Beispiel #10
0
int testlib_function(const int* array, int arrayLength, int64* result) {

	int i, j;
	FARF(ALWAYS, "===============     DSP: Entering function testlib_function ===============");

	*result = 0;

	for (i = 0; i < 100; ++i) {
		for (j = 0; j < arrayLength; ++j) {
			*result += array[i];
		}
	}

	return 0;
}
Beispiel #11
0
int dspal_tester_spi_exceed_max_length_test(void)
{
    int spi_fildes = SUCCESS;
    int result = SUCCESS;
    uint8_t write_data_buffer[DSPAL_SPI_TRANSMIT_BUFFER_LENGTH + 1];
    uint8_t read_data_buffer[DSPAL_SPI_RECEIVE_BUFFER_LENGTH + 1];
    struct dspal_spi_ioctl_loopback loopback;
    struct dspal_spi_ioctl_read_write read_write;

    FARF(MEDIUM, "testing spi open for: %s", SPI_DEVICE_PATH);
    spi_fildes = open(SPI_DEVICE_PATH, 0);

    if (spi_fildes < SUCCESS) {
        FARF(HIGH, "error: failed to open spi device path: %s", SPI_DEVICE_PATH);
        result = ERROR;
        goto exit;
    }

    /*
     * Enable loopback mode to allow write/reads to be tested internally.
     */
    FARF(MEDIUM, "enabling spi loopback mode");
    loopback.state = SPI_LOOPBACK_STATE_ENABLED;
    result = ioctl(spi_fildes, SPI_IOCTL_LOOPBACK_TEST, &loopback);

    if (result < SUCCESS) {
        FARF(HIGH, "error: unable to activate spi loopback mode");
        goto exit;
    }

    read_write.read_buffer = &read_data_buffer[0];
    read_write.read_buffer_length = sizeof(read_data_buffer);
    read_write.write_buffer = &write_data_buffer[0];
    read_write.write_buffer_length = sizeof(write_data_buffer);
    result = ioctl(spi_fildes, SPI_IOCTL_RDWR, &read_write);

    if (result == SUCCESS) {
        FARF(ALWAYS, "error: SPI_IOCTL_RDWR transfer overly large data should "
             "have failed but didn't. ");
        goto exit;
    }

    result = SUCCESS;
    FARF(MEDIUM, "SPI exceed max write length test passed");

exit:

    if (spi_fildes > SUCCESS) {
        close(spi_fildes);
    }

    return result;
}
Beispiel #12
0
/**
* @brief Test file fsync operation
*
* @par
* Test:
* 1) open file with dspal path prefix ('/dev/fs/test.txt') in read/write mode
* 2) write timestamp to file
* 3) fsync on the file
* 4) close the file
* 5) Opens the same file with read only mode
* 6) read the file and compare with the content written in step 3
* 7) close the file
*
* @return
* TEST_PASS ------ if all operations succeed
* TEST_FAIL ------ otherwise
*/
int dspal_tester_test_posix_file_fsync(void)
{
   int fd;
   int bytes_read;
   char wbuf[100];
   char rbuf[100];
   uint64_t timestamp = time(NULL);

   FARF(MEDIUM, "%s test", __FUNCTION__);

   // Open the file in read/write mode
   fd = open(TEST_FILE_PATH, O_RDWR|O_CREAT|O_TRUNC);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode.");
   }
   FARF(MEDIUM, "open /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode");

   // write timestamp
   memset(wbuf, 0, 100);
   sprintf(wbuf, "test - timestamp: %llu\n", timestamp);
   if (write(fd, wbuf, strlen(wbuf)) != (int)strlen(wbuf))
   {
      FAIL("failed to write /dev/fs/test.txt");
   }
   FARF(MEDIUM, "written to %s: %s (len: %d)", TEST_FILE_PATH, wbuf,
        strlen(wbuf));

   // fsync fd to flush the content to storage device
   if (fsync(fd) < 0)
   {
      FAIL("failed to fsync /dev/fs/test.txt");
   }
   FARF(MEDIUM, "fsync() succ");

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   // Open the file in read/write mode
   fd = open(TEST_FILE_PATH, O_RDONLY);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDONLY mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDONLY mode");

   // read the content to ensure the timestamp is properly written to file
   memset(rbuf, 0, 100);
   bytes_read = read(fd, rbuf, sizeof(rbuf)-1);
   FARF(MEDIUM, "read %d bytes from /dev/fs/test.txt:\n%s", bytes_read, rbuf);

   if ((!(strncmp(wbuf, rbuf, bytes_read) == 0) && (bytes_read == (int)strlen(wbuf))))
   {
      FAIL("file write and read content does not match");
   }

   // test writing file in O_RDONLY mode
   int ret = write(fd, wbuf, strlen(wbuf));
   if (ret >= 0)
   {
      FAIL("write() succ on file in O_RDONLY mode. This should never happen!");
   }
   FARF(MEDIUM, "write() failed on file in O_RDONLY mode.");

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   return TEST_PASS;
}
Beispiel #13
0
/**
 * @brief Test opening file in O_APPEND mode
 *
 * @par
 * 1) open the file in O_RDWR|O_APPEND mode
 * 2) read file content
 * 3) write something
 * 4) close the file
 * 5) open the file in O_RDONLY mode
 * 6) read the file and verify the content
 * 7) close the file
 *
 * @return
 * TEST_PASS ------- file properly appended
 * TEST_FAIL ------- on error
 */
int dspal_tester_test_posix_file_open_append()
{
   int fd;
   int bytes_read;
   char rbuf[100];
   const char *old_content = "old content\n";
   const char *new_content = "new content\n";

   FARF(MEDIUM, "%s test", __FUNCTION__);

   fd = open(TEST_FILE_PATH, O_RDWR|O_TRUNC|O_CREAT);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_TRUNC|O_CREAT mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_CREAT|O_TRUNC mode");

   if (write(fd, old_content, strlen(old_content)) != (int)strlen(old_content))
   {
      FAIL("failed to write /dev/fs/test.txt");
   }
   FARF(MEDIUM, "writing to %s: %s (len: %d)", TEST_FILE_PATH, old_content,
        strlen(old_content));

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   // Open the file in APPEND mode
   fd = open(TEST_FILE_PATH, O_RDWR|O_APPEND);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDWR|O_APPEND mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDWR|O_APPEND mode");

   if (write(fd, new_content, strlen(new_content)) != (int)strlen(new_content))
   {
      FAIL("failed to write /dev/fs/test.txt");
   }
   FARF(MEDIUM, "writing to %s: %s (len: %d)", TEST_FILE_PATH, new_content,
        strlen(new_content));

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   // open the file in read only mode
   fd = open(TEST_FILE_PATH, O_RDONLY);
   if (fd < 0)
   {
      FAIL("failed to open /dev/fs/test.txt in O_RDONLY mode.");
   }
   FARF(MEDIUM, "opened /dev/fs/test.txt in O_RDONLY mode");

   memset(rbuf, 0, 100);
   bytes_read = read(fd, rbuf, sizeof(rbuf));
   if (bytes_read < 0)
   {
      FAIL("failed to read /dev/fs/test.txt.");
   }
   else if (bytes_read == 0)
   {
      FAIL("/dev/fs/test.txt is empty");
   }

   if (!(strstr(rbuf, old_content) == rbuf) &&
       strstr(rbuf + strlen(old_content), new_content) ==
         rbuf+strlen(old_content))
   {
      FAIL("failed to append writing to /dev/fs/test.txt");
   }

   FARF(MEDIUM, "succ to append file using O_APPEND");

   close(fd);
   FARF(MEDIUM, "closed /dev/fs/test.txt");

   return TEST_PASS;
}
Beispiel #14
0
/**
* @brief Test read/write functionality of spi by using loopback
*
* @par Detailed Description:
* Tests the read and write functionality of the spi device by putting the device
* in loopback mode.  This is tested in 2 ways: writing the data then reading it
* back from the read buffer or by doing the read/write at the same time using ioctl
*
* Test:
* 1) Opens file for spi device ('/dev/spi-8')
* 2) Sets up the spi device in loopback mode using ioctl
* 3) Write to the spi bus
* 4) Read from the spi bus buffer
* 5) Commented Out ---- Check if data written matches data read
* 6) Loop though steps 4-5 for  SPI_TEST_CYCLES number of cycles
* 7) So ioctl read/write operation and check if data written matches data read
* 8) Close spi bus
*
* @return
* SUCCESS  ------ Test Passes
* ERROR ------ Test Failed
*/
int dspal_tester_spi_loopback_test(void)
{
    int spi_fildes = SUCCESS;
    int cycle_count;
    int result = SUCCESS;
    uint8_t write_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH];
    uint8_t read_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH];
    int test_data_length_in_bytes = SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1;
    struct dspal_spi_ioctl_loopback loopback;
    struct dspal_spi_ioctl_read_write read_write;

    FARF(MEDIUM, "testing spi open for: %s", SPI_DEVICE_PATH);
    spi_fildes = open(SPI_DEVICE_PATH, 0);

    if (spi_fildes < SUCCESS) {
        FARF(HIGH, "error: failed to open spi device path: %s", SPI_DEVICE_PATH);
        result = ERROR;
        goto exit;
    }

    /*
     * Initialize the write buffers in preparation for a read/write sequence.
     */
    write_data_buffer[SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1] = 0;
    init_write_buffer(write_data_buffer, SPI_LOOPBACK_TEST_TRANSMIT_BUFFER_LENGTH - 1);

    /*
     * Enable loopback mode to allow write/reads to be tested internally.
     */
    FARF(MEDIUM, "enabling spi loopback mode");
    loopback.state = SPI_LOOPBACK_STATE_ENABLED;
    result = ioctl(spi_fildes, SPI_IOCTL_LOOPBACK_TEST, &loopback);

    if (result < SUCCESS) {
        FARF(HIGH, "error: unable to activate spi loopback mode");
        goto exit;
    }

    /*
     * Test loopback mode using combined read/write mode.
     */
    FARF(MEDIUM, "testing spi write/read for %d cycles", SPI_TEST_CYCLES);

    for (cycle_count = 0; cycle_count < SPI_TEST_CYCLES; cycle_count++) {
        memset(read_data_buffer, 0, sizeof(read_data_buffer));
        read_write.read_buffer = &read_data_buffer[0];
        read_write.read_buffer_length = test_data_length_in_bytes;
        read_write.write_buffer = &write_data_buffer[0];
        read_write.write_buffer_length = test_data_length_in_bytes;

        FARF(MEDIUM, "writing bytes: (%d bytes)",
             test_data_length_in_bytes);

        result = ioctl(spi_fildes, SPI_IOCTL_RDWR, &read_write);

        if (result < SUCCESS) {
            FARF(ALWAYS, "error: unable to activate read/write ioctl");
            goto exit;
        }

        if (!dpsal_tester_is_memory_matching(write_data_buffer, read_data_buffer, test_data_length_in_bytes)) {
            FARF(ALWAYS, "error: read/write memory buffers do not match");
            goto exit;
        }

        FARF(MEDIUM, "written data matches read data");
    }

    result = SUCCESS;
    FARF(MEDIUM, "SPI lookback test passed");

exit:

    if (spi_fildes > SUCCESS) {
        close(spi_fildes);
    }

    return result;
}