diff --git a/software/libcariboulite/src/caribou_smi/kernel/smi_module_tester.c.bak b/software/libcariboulite/src/caribou_smi/kernel/smi_module_tester.c.bak deleted file mode 100644 index d7c4f2f..0000000 --- a/software/libcariboulite/src/caribou_smi/kernel/smi_module_tester.c.bak +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../caribou_smi.h" -#include "old/bcm2835_smi.h" - - -#define SMI_STREAM_IOC_GET_NATIVE_BUF_SIZE _IO(BCM2835_SMI_IOC_MAGIC, 3) -#define SMI_STREAM_IOC_SET_NON_BLOCK_READ _IO(BCM2835_SMI_IOC_MAGIC, 4) -#define SMI_STREAM_IOC_SET_NON_BLOCK_WRITE _IO(BCM2835_SMI_IOC_MAGIC, 5) -#define SMI_STREAM_IOC_SET_STREAM_STATUS _IO(BCM2835_SMI_IOC_MAGIC, 6) - -static void setup_settings (struct smi_settings *settings) -{ - settings->read_setup_time = 0; - settings->read_strobe_time = 5; - settings->read_hold_time = 0; - settings->read_pace_time = 0; - settings->write_setup_time = 0; - settings->write_hold_time = 0; - settings->write_pace_time = 0; - settings->write_strobe_time = 4; - settings->data_width = SMI_WIDTH_8BIT; - settings->dma_enable = 1; - settings->pack_data = 1; - settings->dma_passthrough_enable = 1; -} - -pthread_t tid; -int fd = -1; -size_t native_batch_length_bytes = 0; -int thread_running = 0; - -void* read_thread(void *arg) -{ - fd_set set; - int rv; - int timeout_num_millisec = 500; - uint8_t *buffer = malloc(native_batch_length_bytes); - int size_of_buf = native_batch_length_bytes; - - while (thread_running) - { - while (1) - { - struct timeval timeout = {0}; - FD_ZERO(&set); // clear the set mask - FD_SET(fd, &set); // add our file descriptor to the set - and only it - int num_sec = timeout_num_millisec / 1000; - timeout.tv_sec = num_sec; - timeout.tv_usec = (timeout_num_millisec - num_sec*1000) * 1000; - - rv = select(fd + 1, &set, NULL, NULL, &timeout); - if(rv == -1) - { - int error = errno; - switch(error) - { - case EINTR: // A signal was caught. - continue; - - case EBADF: // An invalid file descriptor was given in one of the sets. - // (Perhaps a file descriptor that was already closed, or one on which an error has occurred.) - case EINVAL: // nfds is negative or the value contained within timeout is invalid. - case ENOMEM: // unable to allocate memory for internal tables. - default: goto exit; - }; - } - else if (rv == 0) - { - printf("Read poll timeout\n"); - break; - } - else if (FD_ISSET(fd, &set)) - { - int num_read = read(fd, buffer, size_of_buf); - printf("Read %d bytes\n", num_read); - break; - } - } - } - -exit: - free(buffer); - return NULL; -} - - -int main() -{ - char smi_file[] = "/dev/smi"; - struct smi_settings settings = {0}; - - fd = open(smi_file, O_RDWR); - if (fd < 0) - { - printf("can't open smi driver file '%s'\n", smi_file); - return -1; - } - - // Get the current settings - int ret = ioctl(fd, BCM2835_SMI_IOC_GET_SETTINGS, &settings); - if (ret != 0) - { - printf("failed reading ioctl from smi fd (settings)\n"); - close (fd); - return -1; - } - - // apply the new settings - setup_settings(&settings); - ret = ioctl(fd, BCM2835_SMI_IOC_WRITE_SETTINGS, &settings); - if (ret != 0) - { - printf("failed writing ioctl to the smi fd (settings)\n"); - close (fd); - return -1; - } - - // set the address to idle - ret = ioctl(fd, BCM2835_SMI_IOC_ADDRESS, caribou_smi_address_idle); - if (ret != 0) - { - printf("failed setting smi address (idle / %d) to device\n", caribou_smi_address_idle); - close (fd); - return -1; - } - - // get the native batch length in bytes - ret = ioctl(fd, SMI_STREAM_IOC_GET_NATIVE_BUF_SIZE, &native_batch_length_bytes); - if (ret != 0) - { - printf("failed reading native batch length, setting default\n"); - native_batch_length_bytes = (1024)*(1024)/2; - } - printf("Native batch size: %u\n", native_batch_length_bytes); - - // start streaming data - ret = ioctl(fd, SMI_STREAM_IOC_SET_STREAM_STATUS, 1); - - // start the reader thread - thread_running = 1; - int err = pthread_create(&tid, NULL, &read_thread, NULL); - if (err != 0) - { - printf("\ncan't create thread :[%s]", strerror(err)); - } - - getchar(); - thread_running = 0; - - pthread_join(tid, NULL); - - ret = ioctl(fd, SMI_STREAM_IOC_SET_STREAM_STATUS, 0); - - close (fd); - return 0; -} \ No newline at end of file diff --git a/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.c b/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.c index 29b4f71..ca95657 100644 --- a/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.c +++ b/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.c @@ -176,7 +176,7 @@ static void set_state(smi_stream_state_en state) { inst->cur_address = (smi_stream_dir_device_to_smi<cur_address = smi_stream_dir_smi_to_device<transaction_lock); + dev_err(inst->dev, "smi_init_programmed_read returned %d", ret); + return 0; + } } else { - smi_init_programmed_write(inst, DMA_BOUNCE_BUFFER_SIZE); + int ret = smi_init_programmed_write(inst, DMA_BOUNCE_BUFFER_SIZE); + if (ret != 0) + { + spin_unlock(&inst->transaction_lock); + dev_err(inst->dev, "smi_init_programmed_write returned %d", ret); + return 0; + } } //printk(KERN_ERR DRIVER_NAME": SPIN-UNLOCK\n"); @@ -517,6 +541,10 @@ int reader_thread_stream_function(void *pv) // check if the streaming state is on, if not, sleep and check again if (inst->state != smi_stream_rx_channel_0 && inst->state != smi_stream_rx_channel_1) { + //mutex_lock(&inst->read_lock); + //kfifo_reset(&inst->rx_fifo); + //mutex_unlock(&inst->read_lock); + msleep(5); continue; } @@ -531,8 +559,10 @@ int reader_thread_stream_function(void *pv) count = stream_smi_user_dma(inst->smi_inst, DMA_DEV_TO_MEM, &bounce, current_dma_buffer); if (count != DMA_BOUNCE_BUFFER_SIZE || bounce == NULL) { - dev_err(inst->dev, "reader_thread return illegal count = %d", count); - //current_dma_buffer = 1-current_dma_buffer; + dev_err(inst->dev, "stream_smi_user_dma returned illegal count = %d", count); + spin_lock(&inst->smi_inst->transaction_lock); + dmaengine_terminate_sync(inst->smi_inst->dma_chan); + spin_unlock(&inst->smi_inst->transaction_lock); continue; } @@ -570,7 +600,10 @@ int reader_thread_stream_function(void *pv) // try to wait more, unless someone tells us to stop if (down_timeout(&bounce->callback_sem, msecs_to_jiffies(1000))) { - dev_info(inst->dev, "DMA bounce timed out"); + dev_info(inst->dev, "Reader DMA bounce timed out"); + spin_lock(&inst->smi_inst->transaction_lock); + dmaengine_terminate_sync(inst->smi_inst->dma_chan); + spin_unlock(&inst->smi_inst->transaction_lock); } else { @@ -612,7 +645,7 @@ int writer_thread_stream_function(void *pv) while(!kthread_should_stop()) { // check if the streaming state is on, if not, sleep and check again - if (inst->state != smi_stream_tx) + if (inst->state != smi_stream_tx_channel) { msleep(5); continue; @@ -654,15 +687,25 @@ int writer_thread_stream_function(void *pv) if (count != DMA_BOUNCE_BUFFER_SIZE) { // error + dev_err(inst->dev, "stream_smi_user_dma error"); continue; } // Wait for current chunk to complete if (down_timeout(&bounce->callback_sem, msecs_to_jiffies(1000))) { - dev_err(inst->dev, "DMA bounce timed out"); + dev_err(inst->dev, "Writer DMA bounce timed out"); + spin_lock(&inst->smi_inst->transaction_lock); + dmaengine_terminate_sync(inst->smi_inst->dma_chan); + spin_unlock(&inst->smi_inst->transaction_lock); } } + else + { + // if doen't have enough data, invoke poll + inst->writeable = true; + wake_up_interruptible(&inst->poll_event); + } } dev_info(inst->dev, "Left writer thread"); diff --git a/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.h b/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.h index 6b617d8..087fee5 100644 --- a/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.h +++ b/software/libcariboulite/src/caribou_smi/kernel/smi_stream_dev.h @@ -69,7 +69,7 @@ typedef enum smi_stream_idle = 0, smi_stream_rx_channel_0 = 1, smi_stream_rx_channel_1 = 2, - smi_stream_tx = 3, + smi_stream_tx_channel = 3, } smi_stream_state_en; #ifdef __KERNEL__