diff options
Diffstat (limited to 'c/src/lib/libcpu/bfin/serial/twi.c')
-rw-r--r-- | c/src/lib/libcpu/bfin/serial/twi.c | 253 |
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; -} - |