Skip to content

Commit

Permalink
update firmware for tx control signals output on pmod
Browse files Browse the repository at this point in the history
added dsp flow example
  • Loading branch information
David Michaeli committed Mar 16, 2024
1 parent 21a9733 commit 1b34c56
Show file tree
Hide file tree
Showing 20 changed files with 25,756 additions and 25,693 deletions.
2 changes: 1 addition & 1 deletion driver/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ USERSPACE_SMI_DIR="../software/libcariboulite/src/caribou_smi/kernel"

## FUNCTIONS
install() {
local mtu_mult=${1:-6}
local mtu_mult=${1:-16}
local dir_offs=${2:-2}
local ch_offs=${3:-3}

Expand Down
20 changes: 13 additions & 7 deletions driver/smi_stream_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ static int set_state(smi_stream_state_en new_state)

if (new_state == smi_stream_tx_channel)
{
ret = transfer_thread_init(inst,DMA_MEM_TO_DEV,stream_smi_write_dma_callback);
ret = transfer_thread_init(inst, DMA_MEM_TO_DEV, stream_smi_write_dma_callback);
}
else
{
ret = transfer_thread_init(inst,DMA_DEV_TO_MEM,stream_smi_read_dma_callback);
ret = transfer_thread_init(inst, DMA_DEV_TO_MEM, stream_smi_read_dma_callback);
}

// if starting the transfer succeeded update the state
Expand Down Expand Up @@ -329,12 +329,14 @@ static int smi_disable_sync(struct bcm2835_smi_instance *smi_inst)

}

/***************************************************************************/
static void smi_refresh_dma_command(struct bcm2835_smi_instance *smi_inst, int num_transfers)
{
int smics_temp = 0;
//print_smil_registers_ext("refresh 1");
write_smi_reg(smi_inst, SMI_TRANSFER_MULTIPLIER*num_transfers, SMIL); //to avoid stopping and restarting
//print_smil_registers_ext("refresh 2");

// Start the transaction
smics_temp = read_smi_reg(smi_inst, SMICS);
smics_temp |= SMICS_START;
Expand All @@ -345,7 +347,7 @@ static void smi_refresh_dma_command(struct bcm2835_smi_instance *smi_inst, int n
}

/***************************************************************************/
static int smi_init_programmed_transfer(struct bcm2835_smi_instance *smi_inst, enum dma_transfer_direction dma_dir,int num_transfers)
static int smi_init_programmed_transfer(struct bcm2835_smi_instance *smi_inst, enum dma_transfer_direction dma_dir, int num_transfers)
{
int smics_temp = 0;
int success = 0;
Expand Down Expand Up @@ -597,6 +599,7 @@ static void stream_smi_read_dma_callback(void *param)
inst->current_read_chunk++;
}

/***************************************************************************/
static void stream_smi_check_and_restart(struct bcm2835_smi_dev_instance *inst)
{
struct bcm2835_smi_instance *smi_inst = inst->smi_inst;
Expand All @@ -621,6 +624,7 @@ static void stream_smi_check_and_restart(struct bcm2835_smi_dev_instance *inst)
}
}

/***************************************************************************/
static void stream_smi_write_dma_callback(void *param)
{
/* Notify the bottom half that a chunk is ready for user copy */
Expand Down Expand Up @@ -656,7 +660,7 @@ static void stream_smi_write_dma_callback(void *param)

}


/***************************************************************************/
static struct dma_async_tx_descriptor *stream_smi_dma_init_cyclic( struct bcm2835_smi_instance *inst,
enum dma_transfer_direction dir,
dma_async_tx_callback callback, void*param)
Expand Down Expand Up @@ -691,14 +695,13 @@ static struct dma_async_tx_descriptor *stream_smi_dma_init_cyclic( struct bcm28
*
***************************************************************************/

int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfer_direction dir,dma_async_tx_callback callback)
int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfer_direction dir, dma_async_tx_callback callback)
{

unsigned int errors = 0;
int ret;
int success;

dev_info(inst->dev, "Starting cyclic transfer");
dev_info(inst->dev, "Starting cyclic transfer, dma dir: %d", dir);
inst->transfer_thread_running = true;

/* Disable the peripheral: */
Expand All @@ -723,6 +726,7 @@ int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfe
{
spin_unlock(&inst->smi_inst->transaction_lock);
}

inst->current_read_chunk = 0;
inst->counter_missed = 0;
if(!errors)
Expand Down Expand Up @@ -896,6 +900,7 @@ static ssize_t smi_stream_write_file(struct file *f, const char __user *user_ptr
num_to_push = num_bytes_available > count ? count : num_bytes_available;
ret = kfifo_from_user(&inst->tx_fifo, user_ptr, num_to_push, &actual_copied);

//dev_info(inst->dev, "smi_stream_write_file: pushed %ld bytes of %ld, available was %ld", actual_copied, count, num_bytes_available);
mutex_unlock(&inst->write_lock);

return ret ? ret : (ssize_t)actual_copied;
Expand Down Expand Up @@ -949,6 +954,7 @@ static dev_t smi_stream_devid;
static struct class *smi_stream_class;
static struct device *smi_stream_dev;

/***************************************************************************/
static int smi_stream_dev_probe(struct platform_device *pdev)
{
int err;
Expand Down
15 changes: 15 additions & 0 deletions examples/cpp_api/async_sample_process/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.2)
project(test_app)

# Find the package using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(CARIBOULITE REQUIRED cariboulite)

# Add the executable
add_executable(test_app main.cpp)

# Include directories from the cariboulite package
target_include_directories(test_app PRIVATE ${CARIBOULITE_INCLUDE_DIRS})

# Link against the cariboulite library
target_link_libraries(test_app PRIVATE ${CARIBOULITE_LIBRARIES} -lcariboulite)
165 changes: 165 additions & 0 deletions examples/cpp_api/async_sample_process/circular_buffer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#ifndef __CIRC_BUFFER_H__
#define __CIRC_BUFFER_H__

#include <string.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <atomic>

#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1)))
#define MIN(x,y) ((x)>(y)?(y):(x))


template <class T>
class circular_buffer {
public:
circular_buffer(size_t size, bool override_write = true, bool block_read = true)
{
max_size_ = size;
if (!IS_POWER_OF_2(max_size_))
{
max_size_ = next_power_of_2(max_size_);
}
buf_ = new T[max_size_];
override_write_ = override_write;
block_read_ = block_read;
}

~circular_buffer()
{
std::unique_lock<std::mutex> lock(mutex_);
delete []buf_;
}

size_t put(const T *data, size_t length)
{
std::lock_guard<std::mutex> lock(mutex_);

if ((max_size_ - size()) < length && override_write_)
{
// pop the amount of data the is needed
tail_ += length - (max_size_ - size());
}

size_t len = MIN(length, max_size_ - head_ + tail_);
auto l = MIN(len, max_size_ - (head_ & (max_size_ - 1)));

memcpy(buf_ + (head_ & (max_size_ - 1)), data, l * sizeof(T));
memcpy(buf_, data + l, (len - l) * sizeof(T));

head_ += len;

if (block_read_)
{
cond_var_.notify_one();
}

return len;
}

size_t get(T *data, size_t length, int timeout_us = 100000)
{
std::unique_lock<std::mutex> lock(mutex_);

if (block_read_)
{
cond_var_.wait_for(lock, std::chrono::microseconds(timeout_us), [&]()
{
// Acquire the lock only if
// we got enough items
return size() >= length;
});

if (size() < length)
{
return 0;
}
}

size_t len = MIN(length, head_ - tail_);
auto l = MIN(len, max_size_ - (tail_ & (max_size_ - 1)));

if (data != NULL)
{
memcpy(data, buf_ + (tail_ & (max_size_ - 1)), l * sizeof(T));
memcpy(data + l, buf_, (len - l) * sizeof(T));
}
tail_ += len;
return len;
}

void put(T item)
{
put(&item, 1);
}

T get()
{
T item;
get(&item, 1);
return item;
}

void reset()
{
std::unique_lock<std::mutex> lock(mutex_);
head_ = tail_ = 0;
}

inline bool empty()
{
return head_ == tail_;
}

inline bool full()
{
return size() == capacity();
}

inline size_t capacity() const
{
return max_size_;
}

size_t size()
{
return (head_ - tail_);
}

void print_buffer()
{
std::unique_lock<std::mutex> lock(mutex_);
size_t t = tail_;
int i = 0;
while (t < head_)
{
printf("%d => %d\n", i++, (int)buf_[t++&(max_size_-1)]);
}
}

private:
uint32_t next_power_of_2 (uint32_t x)
{
uint32_t power = 1;
while(power < x)
{
power <<= 1;
}
return power;
}

private:
std::mutex mutex_;
std::condition_variable cond_var_;

T* buf_;
size_t head_ = 0;
size_t tail_ = 0;
size_t max_size_;
bool override_write_;
bool block_read_;
};

#endif
Loading

0 comments on commit 1b34c56

Please sign in to comment.