summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/bfin/serial/twi.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/bfin/serial/twi.c')
-rw-r--r--c/src/lib/libcpu/bfin/serial/twi.c253
1 files changed, 0 insertions, 253 deletions
diff --git a/c/src/lib/libcpu/bfin/serial/twi.c b/c/src/lib/libcpu/bfin/serial/twi.c
deleted file mode 100644
index 0d6e6ca0b1..0000000000
--- a/c/src/lib/libcpu/bfin/serial/twi.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* this is not much more than a shell; it does not do anything useful yet */
-
-/* TWI (I2C) driver for Blackfin
- *
- * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA
- * written by Allan Hessenflow <allanh@kallisti.com>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-
-#include <stdlib.h>
-#include <rtems.h>
-
-#include <libcpu/twiRegs.h>
-#include <libcpu/twi.h>
-
-
-#ifndef N_BFIN_TWI
-#define N_BFIN_TWI 1
-#endif
-
-#define BFIN_REG16(base, offset) \
- (*((uint16_t volatile *) ((char *)(base) + (offset))))
-
-
-static struct {
- void *base;
- rtems_id irqSem;
- rtems_id mutex;
- bfin_twi_callback_t callback;
- void *callbackArg;
- bfin_twi_request_t volatile *req;
- uint8_t volatile *dataPtr;
- int volatile count;
- bool volatile masterActive;
- rtems_status_code volatile masterResult;
- bool volatile slaveActive;
-} twi[N_BFIN_TWI];
-
-
-rtems_status_code bfin_twi_init(int channel, bfin_twi_config_t *config) {
- rtems_status_code result;
- void *base;
-
- if (channel < 0 || channel >= N_BFIN_TWI)
- return RTEMS_INVALID_NUMBER;
-
- base = config->base;
- twi[channel].base = base;
-
- result = rtems_semaphore_create(rtems_build_name('t','w','i','s'),
- 0,
- RTEMS_FIFO |
- RTEMS_SIMPLE_BINARY_SEMAPHORE |
- RTEMS_NO_INHERIT_PRIORITY |
- RTEMS_NO_PRIORITY_CEILING |
- RTEMS_LOCAL,
- 0,
- &twi[channel].irqSem);
- result = rtems_semaphore_create(rtems_build_name('t','w','i','m'),
- 1,
- RTEMS_PRIORITY |
- RTEMS_SIMPLE_BINARY_SEMAPHORE |
- RTEMS_INHERIT_PRIORITY |
- RTEMS_NO_PRIORITY_CEILING |
- RTEMS_LOCAL,
- 0,
- &twi[channel].mutex);
- BFIN_REG16(base, TWI_CONTROL_OFFSET) =
- (uint16_t) (((config->sclk +9999999) / 10000000) <<
- TWI_CONTROL_PRESCALE_SHIFT) |
- TWI_CONTROL_TWI_ENA;
- BFIN_REG16(base, TWI_CLKDIV_OFFSET) = config->fast ?
- ((8 << TWI_CLKDIV_CLKHI_SHIFT) |
- (17 << TWI_CLKDIV_CLKLOW_SHIFT)) :
- ((33 << TWI_CLKDIV_CLKHI_SHIFT) |
- (67 << TWI_CLKDIV_CLKLOW_SHIFT));
- BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = 0;
- BFIN_REG16(base, TWI_MASTER_CTL_OFFSET) = config->fast ?
- TWI_MASTER_CTL_FAST :
- 0;
- BFIN_REG16(base, TWI_SLAVE_ADDR_OFFSET) = (uint16_t) config->slave_address <<
- TWI_SLAVE_ADDR_SADDR_SHIFT;
- BFIN_REG16(base, TWI_MASTER_STAT_OFFSET) = TWI_MASTER_STAT_BUFWRERR |
- TWI_MASTER_STAT_BUFRDERR |
- TWI_MASTER_STAT_DNAK |
- TWI_MASTER_STAT_ANAK |
- TWI_MASTER_STAT_LOSTARB;
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = TWI_FIFO_CTL_XMTFLUSH |
- TWI_FIFO_CTL_RCVFLUSH;
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = 0;
- BFIN_REG16(base, TWI_INT_STAT_OFFSET) = TWI_INT_STAT_RCVSERV |
- TWI_INT_STAT_XMTSERV |
- TWI_INT_STAT_MERR |
- TWI_INT_STAT_MCOMP |
- TWI_INT_STAT_SOVF |
- TWI_INT_STAT_SERR |
- TWI_INT_STAT_SCOMP |
- TWI_INT_STAT_SINIT;
- BFIN_REG16(base, TWI_INT_MASK_OFFSET) = TWI_INT_MASK_RCVSERVM |
- TWI_INT_MASK_XMTSERVM;
-
- return result;
-}
-
-rtems_status_code bfin_twi_register_callback(int channel,
- bfin_twi_callback_t callback,
- void *arg) {
- void *base;
- int level;
-
- if (channel < 0 || channel >= N_BFIN_TWI)
- return RTEMS_INVALID_NUMBER;
-
- base = twi[channel].base;
- if (callback == NULL)
- BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = 0;
- rtems_interrupt_disable(level);
- twi[channel].callback = callback;
- twi[channel].callbackArg = arg;
- rtems_interrupt_enable(level);
- if (callback != NULL)
- BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = TWI_SLAVE_CTL_GEN |
- TWI_SLAVE_CTL_SEN;
-
- return RTEMS_SUCCESSFUL;
-}
-
-void bfin_twi_isr(int source) {
- void *base;
- int i;
- uint16_t r;
- uint16_t stat;
-
- for (i = 0; i < N_BFIN_TWI; i++) {
- base = twi[i].base;
- if (base) {
- stat = BFIN_REG16(base, TWI_INT_STAT_OFFSET);
- if (stat) {
- BFIN_REG16(base, TWI_INT_STAT_OFFSET) = stat;
- if ((stat & TWI_INT_STAT_SINIT) && !twi[i].slaveActive) {
- twi[i].slaveActive = true;
- r = BFIN_REG16(base, TWI_FIFO_CTL_OFFSET);
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r | TWI_FIFO_CTL_XMTFLUSH;
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r;
- r = BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET);
- BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = r | TWI_SLAVE_CTL_STDVAL;
- }
- if (twi[i].slaveActive) {
-
-
- if (stat & (TWI_INT_STAT_SCOMP | TWI_INT_STAT_SERR)) {
-
-
- r = BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET);
- BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = r & ~TWI_SLAVE_CTL_STDVAL;
- twi[i].slaveActive = false;
-
-
- }
- }
- if (twi[i].masterActive && !twi[i].slaveActive) {
-
-
- if (stat & (TWI_INT_STAT_MCOMP | TWI_INT_STAT_MERR)) {
- if (!(stat & TWI_INT_STAT_MERR)) {
-
-
- rtems_semaphore_release(twi[i].irqSem);
-
-
- } else
- rtems_semaphore_release(twi[i].irqSem);
- }
- }
- }
- }
- }
-}
-
-rtems_status_code bfin_twi_request(int channel, uint8_t address,
- bfin_twi_request_t *request,
- rtems_interval timeout) {
- rtems_status_code result;
- void *base;
- rtems_interrupt_level level;
- uint16_t r;
- uint16_t masterMode;
-
- if (channel < 0 || channel >= N_BFIN_TWI)
- return RTEMS_INVALID_NUMBER;
- result = rtems_semaphore_obtain(twi[channel].mutex,
- RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- if (result == RTEMS_SUCCESSFUL) {
- base = twi[channel].base;
- twi[channel].req = request;
-
- if (request->write) {
- twi[channel].dataPtr = request->data;
- twi[channel].count = request->count;
- } else
- twi[channel].count = 0;
-
- BFIN_REG16(base, TWI_MASTER_ADDR_OFFSET) = (uint16_t) address <<
- TWI_MASTER_ADDR_MADDR_SHIFT;
- masterMode = BFIN_REG16(base, TWI_MASTER_CTL_OFFSET);
- masterMode |= (request->count << TWI_MASTER_CTL_DCNT_SHIFT);
- if (request->next)
- masterMode |= TWI_MASTER_CTL_RSTART;
- if (!request->write)
- masterMode |= TWI_MASTER_CTL_MDIR;
- masterMode |= TWI_MASTER_CTL_MEN;
- rtems_interrupt_disable(level);
- if (!twi[channel].slaveActive) {
- r = BFIN_REG16(base, TWI_FIFO_CTL_OFFSET);
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r | TWI_FIFO_CTL_XMTFLUSH;
- BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r;
- if (request->write) {
- while (twi[channel].count &&
- (BFIN_REG16(base, TWI_FIFO_STAT_OFFSET) &
- TWI_FIFO_STAT_XMTSTAT_MASK) !=
- TWI_FIFO_STAT_XMTSTAT_FULL) {
- BFIN_REG16(base, TWI_XMT_DATA8_OFFSET) =
- (uint16_t) *twi[channel].dataPtr++;
- twi[channel].count--;
- }
- }
- twi[channel].masterActive = true;
- BFIN_REG16(base, TWI_MASTER_CTL_OFFSET) = masterMode;
- } else {
- twi[channel].masterActive = false;
- twi[channel].masterResult = -1; /* BISON (code should be equiv to lost arbitration) */
- }
- rtems_interrupt_enable(level);
- while (result == RTEMS_SUCCESSFUL && twi[channel].masterActive)
- result = rtems_semaphore_obtain(twi[channel].irqSem,
- RTEMS_WAIT, timeout);
- if (result == RTEMS_SUCCESSFUL)
- result = twi[channel].masterResult;
- else {
- /* BISON abort */
-
-
-
- }
- rtems_semaphore_release(twi[channel].mutex);
- }
- return result;
-}
-