Compare commits

..

1 Commits

Author SHA1 Message Date
Clyne 92f4a13b5a try workqueue for efficiency 2 days ago

@ -2,6 +2,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#define FRAME_SIZE (24) #define FRAME_SIZE (24)
@ -11,14 +12,15 @@
// 10'000'000 Hz = 52 kSPS // 10'000'000 Hz = 52 kSPS
#define TRANSFER_HZ (27000000) #define TRANSFER_HZ (27000000)
// TODO: // TODO: minimize 45us delay between xfers
// - Require max CPU clock speed so 130 kSPS can be achieved
// - Minimize ~30us delay between transfers // 24-11-23: We're hitting 130 kSPS initially, but are eventually slowed down
// - Figure out how to get sample data out // to 87 kSPS. Need to investigate high-priority workers, forcing a high SPI
// - Create configuration interface // clock speed, and/or minimizing overall latency.
struct ads1278 struct ads1278
{ {
struct workqueue_struct *wq;
unsigned char *rx; unsigned char *rx;
unsigned char *tx; unsigned char *tx;
dma_addr_t rx_dma_handle; dma_addr_t rx_dma_handle;
@ -29,26 +31,43 @@ struct ads1278
int running[2]; int running[2];
}; };
static void ads1278_transfer_callback1(void *context) static struct spi_device *spip = NULL;
static void ads1278_work_handler(struct work_struct *w)
{ {
struct spi_device *spi = (struct spi_device *)context; struct ads1278 *ads;
struct ads1278 *ads = spi_get_drvdata(spi);
if (!spip)
return;
ads = spi_get_drvdata(spip);
if (!ads->stop_requested) while (!ads->stop_requested) {
spi_async(spi, &ads->msg[0]); spi_sync_locked(spip, &ads->msg[0]);
else }
ads->running[0] = 0;
} }
static DECLARE_WORK(ads1278_work, ads1278_work_handler);
static void ads1278_transfer_callback2(void *context) static void ads1278_transfer_callback1(void *context)
{ {
struct spi_device *spi = (struct spi_device *)context; // struct spi_device *spi = (struct spi_device *)context;
struct ads1278 *ads = spi_get_drvdata(spi); // struct ads1278 *ads = spi_get_drvdata(spi);
//
// if (!ads->stop_requested)
// queue_work(ads->wq, &ads1278_work);
// //spi_async(spi, &ads->msg[0]);
// else
// ads->running[0] = 0;
}
if (!ads->stop_requested) static void ads1278_transfer_callback2(void *context)
spi_async(spi, &ads->msg[1]); {
else // struct spi_device *spi = (struct spi_device *)context;
ads->running[1] = 0; // struct ads1278 *ads = spi_get_drvdata(spi);
//
// if (!ads->stop_requested)
// spi_async(spi, &ads->msg[1]);
// else
// ads->running[1] = 0;
} }
@ -119,8 +138,16 @@ static int ads1278_begin_transfer(struct spi_device *spi)
ads->running[0] = 1; ads->running[0] = 1;
ads->running[1] = 1; ads->running[1] = 1;
/* TODO ret = */ spi_async(spi, &ads->msg[0]); // /* TODO ret = */ spi_async(spi, &ads->msg[0]);
return spi_async(spi, &ads->msg[1]); // return spi_async(spi, &ads->msg[1]);
ads->wq = create_singlethread_workqueue("ads1278");
if (ads->wq) {
spip = spi;
queue_work(ads->wq, &ads1278_work);
}
return 0;
} }
static int ads1278_probe(struct spi_device *spi) static int ads1278_probe(struct spi_device *spi)
@ -149,6 +176,7 @@ static int ads1278_probe(struct spi_device *spi)
dev_info(&spi->dev, "ready to go!"); dev_info(&spi->dev, "ready to go!");
spi_bus_lock(spi->controller);
if (ads1278_begin_transfer(spi)) { if (ads1278_begin_transfer(spi)) {
dev_err(&spi->dev, "error with initial transfer!"); dev_err(&spi->dev, "error with initial transfer!");
goto end_free_ads; goto end_free_ads;
@ -184,9 +212,14 @@ static void ads1278_remove(struct spi_device *spi)
dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->tx, ads->tx_dma_handle); dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->tx, ads->tx_dma_handle);
dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->rx, ads->rx_dma_handle); dma_free_coherent(&spi->dev, TRANSFER_SIZE * 2, ads->rx, ads->rx_dma_handle);
flush_scheduled_work();
if (ads->wq)
destroy_workqueue(ads->wq);
kfree(ads); kfree(ads);
} }
spi_bus_unlock(spi->controller);
dev_info(&spi->dev, "done."); dev_info(&spi->dev, "done.");
} }

Loading…
Cancel
Save