summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-05-05 09:10:47 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-05-05 09:10:47 -0600
commit460e68e984bb7f0f14e5e750fdb6d112da862a5a (patch)
tree07aabc8bbfbe0acadba90373c8ec7e2507c8f689 /nuttx/arch/arm/src
parent1b7d3b3dbcff1355cd127808828d18a6a96c77c1 (diff)
downloadpx4-nuttx-460e68e984bb7f0f14e5e750fdb6d112da862a5a.tar.gz
px4-nuttx-460e68e984bb7f0f14e5e750fdb6d112da862a5a.tar.bz2
px4-nuttx-460e68e984bb7f0f14e5e750fdb6d112da862a5a.zip
Make Pirelli-DLP10 a true board configuration; Calypso no compiles without errors
Diffstat (limited to 'nuttx/arch/arm/src')
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_armio.c61
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_irq.c288
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_keypad.c1
-rw-r--r--nuttx/arch/arm/src/calypso/calypso_spi.c244
4 files changed, 337 insertions, 257 deletions
diff --git a/nuttx/arch/arm/src/calypso/calypso_armio.c b/nuttx/arch/arm/src/calypso/calypso_armio.c
index 56f049f94..8699533c6 100644
--- a/nuttx/arch/arm/src/calypso/calypso_armio.c
+++ b/nuttx/arch/arm/src/calypso/calypso_armio.c
@@ -47,30 +47,29 @@
* HW access
****************************************************************************/
-#define BASE_ADDR_ARMIO 0xfffe4800
-#define ARMIO_REG(x) ((void *)BASE_ADDR_ARMIO + (x))
+#define BASE_ADDR_ARMIO 0xfffe4800
+#define ARMIO_REG(x) (BASE_ADDR_ARMIO + (x))
enum armio_reg {
- LATCH_IN = 0x00,
- LATCH_OUT = 0x02,
- IO_CNTL = 0x04,
- CNTL_REG = 0x06,
- LOAD_TIM = 0x08,
- KBR_LATCH_REG = 0x0a,
- KBC_REG = 0x0c,
- BUZZ_LIGHT_REG = 0x0e,
- LIGHT_LEVEL = 0x10,
- BUZZER_LEVEL = 0x12,
- GPIO_EVENT_MODE = 0x14,
- KBD_GPIO_INT = 0x16,
- KBD_GPIO_MASKIT = 0x18,
- GPIO_DEBOUNCING = 0x1a,
- GPIO_LATCH = 0x1c,
+ LATCH_IN = 0x00,
+ LATCH_OUT = 0x02,
+ IO_CNTL = 0x04,
+ CNTL_REG = 0x06,
+ LOAD_TIM = 0x08,
+ KBR_LATCH_REG = 0x0a,
+ KBC_REG = 0x0c,
+ BUZZ_LIGHT_REG = 0x0e,
+ LIGHT_LEVEL = 0x10,
+ BUZZER_LEVEL = 0x12,
+ GPIO_EVENT_MODE = 0x14,
+ KBD_GPIO_INT = 0x16,
+ KBD_GPIO_MASKIT = 0x18,
+ GPIO_DEBOUNCING = 0x1a,
+ GPIO_LATCH = 0x1c,
};
-#define KBD_INT (1<<0)
-#define GPIO_INT (1<<1)
-
+#define KBD_INT (1 << 0)
+#define GPIO_INT (1 << 1)
/****************************************************************************
* ARMIO interrupt handler
@@ -80,25 +79,25 @@ enum armio_reg {
static int kbd_gpio_irq(int irq, uint32_t *regs)
{
- calypso_kbd_irq();
-
- return 0;
+ return calypso_kbd_irq(irq, regs);
}
-
/****************************************************************************
* Initialize ARMIO
****************************************************************************/
void calypso_armio(void)
{
- /* Enable ARMIO clock */
- putreg16(1<<5, ARMIO_REG(CNTL_REG));
+ /* Enable ARMIO clock */
+
+ putreg16(1<<5, ARMIO_REG(CNTL_REG));
+
+ /* Mask GPIO interrupt and keypad interrupt */
+
+ putreg16(KBD_INT|GPIO_INT, ARMIO_REG(KBD_GPIO_MASKIT));
- /* Mask GPIO interrupt and keypad interrupt */
- putreg16(KBD_INT|GPIO_INT, ARMIO_REG(KBD_GPIO_MASKIT));
+ /* Attach and enable the interrupt */
- /* Attach and enable the interrupt */
- irq_attach(IRQ_KEYPAD_GPIO, (xcpt_t)kbd_gpio_irq);
- up_enable_irq(IRQ_KEYPAD_GPIO);
+ irq_attach(IRQ_KEYPAD_GPIO, (xcpt_t)kbd_gpio_irq);
+ up_enable_irq(IRQ_KEYPAD_GPIO);
}
diff --git a/nuttx/arch/arm/src/calypso/calypso_irq.c b/nuttx/arch/arm/src/calypso/calypso_irq.c
index fa818df40..e307dd38c 100644
--- a/nuttx/arch/arm/src/calypso/calypso_irq.c
+++ b/nuttx/arch/arm/src/calypso/calypso_irq.c
@@ -47,7 +47,9 @@
#include <stdint.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
+
#include <arch/calypso/memory.h>
+#include <arch/calypso/clock.h>
#include "arm.h"
#include "up_arch.h"
@@ -56,21 +58,22 @@
* Pre-processor Definitions
****************************************************************************/
-#define BASE_ADDR_IRQ 0xfffffa00
-#define BASE_ADDR_IBOOT_EXC 0x0080001C
-
-enum irq_reg {
- IT_REG1 = 0x00,
- IT_REG2 = 0x02,
- MASK_IT_REG1 = 0x08,
- MASK_IT_REG2 = 0x0a,
- IRQ_NUM = 0x10,
- FIQ_NUM = 0x12,
- IRQ_CTRL = 0x14,
+#define BASE_ADDR_IRQ 0xfffffa00
+#define BASE_ADDR_IBOOT_EXC 0x0080001C
+
+enum irq_reg
+{
+ IT_REG1 = 0x00,
+ IT_REG2 = 0x02,
+ MASK_IT_REG1 = 0x08,
+ MASK_IT_REG2 = 0x0a,
+ IRQ_NUM = 0x10,
+ FIQ_NUM = 0x12,
+ IRQ_CTRL = 0x14,
};
-#define ILR_IRQ(x) (0x20 + (x*2))
-#define IRQ_REG(x) ((void *)BASE_ADDR_IRQ + (x))
+#define ILR_IRQ(x) (0x20 + (x*2))
+#define IRQ_REG(x) (BASE_ADDR_IRQ + (x))
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -87,28 +90,29 @@ extern uint32_t _exceptions;
* Private Data
****************************************************************************/
-static uint8_t default_irq_prio[] = {
- [IRQ_WATCHDOG] = 0xff,
- [IRQ_TIMER1] = 0xff,
- [IRQ_TIMER2] = 0xff,
- [IRQ_TSP_RX] = 0,
- [IRQ_TPU_FRAME] = 3,
- [IRQ_TPU_PAGE] = 0xff,
- [IRQ_SIMCARD] = 0xff,
- [IRQ_UART_MODEM] = 8,
- [IRQ_KEYPAD_GPIO] = 4,
- [IRQ_RTC_TIMER] = 9,
- [IRQ_RTC_ALARM_I2C] = 10,
- [IRQ_ULPD_GAUGING] = 2,
- [IRQ_EXTERNAL] = 12,
- [IRQ_SPI] = 0xff,
- [IRQ_DMA] = 0xff,
- [IRQ_API] = 0xff,
- [IRQ_SIM_DETECT] = 0,
- [IRQ_EXTERNAL_FIQ] = 7,
- [IRQ_UART_IRDA] = 2,
- [IRQ_ULPD_GSM_TIMER] = 1,
- [IRQ_GEA] = 0xff,
+static uint8_t default_irq_prio[] =
+{
+ [IRQ_WATCHDOG] = 0xff,
+ [IRQ_TIMER1] = 0xff,
+ [IRQ_TIMER2] = 0xff,
+ [IRQ_TSP_RX] = 0,
+ [IRQ_TPU_FRAME] = 3,
+ [IRQ_TPU_PAGE] = 0xff,
+ [IRQ_SIMCARD] = 0xff,
+ [IRQ_UART_MODEM] = 8,
+ [IRQ_KEYPAD_GPIO] = 4,
+ [IRQ_RTC_TIMER] = 9,
+ [IRQ_RTC_ALARM_I2C] = 10,
+ [IRQ_ULPD_GAUGING] = 2,
+ [IRQ_EXTERNAL] = 12,
+ [IRQ_SPI] = 0xff,
+ [IRQ_DMA] = 0xff,
+ [IRQ_API] = 0xff,
+ [IRQ_SIM_DETECT] = 0,
+ [IRQ_EXTERNAL_FIQ] = 7,
+ [IRQ_UART_IRDA] = 2,
+ [IRQ_ULPD_GSM_TIMER] = 1,
+ [IRQ_GEA] = 0xff,
};
/****************************************************************************
@@ -117,53 +121,66 @@ static uint8_t default_irq_prio[] = {
static void _irq_enable(enum irq_nr nr, int enable)
{
- uint16_t *reg = IRQ_REG(MASK_IT_REG1);
- uint16_t val;
-
- if (nr > 15) {
- reg = IRQ_REG(MASK_IT_REG2);
- nr -= 16;
- }
-
- val = getreg16(reg);
- if (enable)
- val &= ~(1 << nr);
- else
- val |= (1 << nr);
- putreg16(val, reg);
+ uintptr_t reg = IRQ_REG(MASK_IT_REG1);
+ uint16_t val;
+
+ if (nr > 15)
+ {
+ reg = IRQ_REG(MASK_IT_REG2);
+ nr -= 16;
+ }
+
+ val = getreg16(reg);
+ if (enable)
+ {
+ val &= ~(1 << nr);
+ }
+ else
+ {
+ val |= (1 << nr);
+ }
+
+ putreg16(val, reg);
}
static void set_default_priorities(void)
{
- unsigned int i;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++)
+ {
+ uint16_t val;
+ uint8_t prio = default_irq_prio[i];
- for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) {
- uint16_t val;
- uint8_t prio = default_irq_prio[i];
- if (prio > 31)
- prio = 31;
+ if (prio > 31)
+ {
+ prio = 31;
+ }
- val = getreg16(IRQ_REG(ILR_IRQ(i)));
- val &= ~(0x1f << 2);
- val |= prio << 2;
+ val = getreg16(IRQ_REG(ILR_IRQ(i)));
+ val &= ~(0x1f << 2);
+ val |= prio << 2;
- /* Make edge mode default. Hopefully causes less trouble */
- val |= 0x02;
+ /* Make edge mode default. Hopefully causes less trouble */
- putreg16(val, IRQ_REG(ILR_IRQ(i)));
- }
+ val |= 0x02;
+
+ putreg16(val, IRQ_REG(ILR_IRQ(i)));
+ }
}
/* Install the exception handlers to where the ROM loader jumps */
+
static void calypso_exceptions_install(void)
{
- uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC;
- uint32_t *exceptions_src = &_exceptions;
- int i;
-
- for (i = 0; i < 7; i++)
- *exceptions_dst++ = *exceptions_src++;
-
+ uint32_t *exceptions_dst = (uint32_t *) BASE_ADDR_IBOOT_EXC;
+ uint32_t *exceptions_src = &_exceptions;
+ int i;
+
+ for (i = 0; i < 7; i++)
+ {
+ *exceptions_dst++ = *exceptions_src++;
+ }
}
/****************************************************************************
@@ -180,27 +197,32 @@ static void calypso_exceptions_install(void)
void up_irqinitialize(void)
{
- /* Prepare hardware */
- calypso_exceptions_install();
- current_regs = NULL;
+ /* Prepare hardware */
+
+ calypso_exceptions_install();
+ current_regs = NULL;
- /* Switch to internal ROM */
- calypso_bootrom(1);
+ /* Switch to internal ROM */
- /* set default priorities */
- set_default_priorities();
+ calypso_bootrom(1);
- /* mask all interrupts off */
- putreg16(0xffff, IRQ_REG(MASK_IT_REG1));
- putreg16(0xffff, IRQ_REG(MASK_IT_REG2));
+ /* Set default priorities */
- /* clear all pending interrupts */
- putreg16(0, IRQ_REG(IT_REG1));
- putreg16(0, IRQ_REG(IT_REG2));
+ set_default_priorities();
+
+ /* Mask all interrupts off */
+
+ putreg16(0xffff, IRQ_REG(MASK_IT_REG1));
+ putreg16(0xffff, IRQ_REG(MASK_IT_REG2));
+
+ /* clear all pending interrupts */
+ putreg16(0, IRQ_REG(IT_REG1));
+ putreg16(0, IRQ_REG(IT_REG2));
+
+ /* Enable interrupts globally to the ARM core */
- /* enable interrupts globally to the ARM core */
#ifndef CONFIG_SUPPRESS_INTERRUPTS
- irqrestore(SVC_MODE | PSR_F_BIT);
+ irqrestore(SVC_MODE | PSR_F_BIT);
#endif
}
@@ -214,8 +236,10 @@ void up_irqinitialize(void)
void up_disable_irq(int irq)
{
- if((unsigned)irq < NR_IRQS)
- _irq_enable(irq, 0);
+ if ((unsigned)irq < NR_IRQS)
+ {
+ _irq_enable(irq, 0);
+ }
}
/****************************************************************************
@@ -228,8 +252,10 @@ void up_disable_irq(int irq)
void up_enable_irq(int irq)
{
- if((unsigned)irq < NR_IRQS)
- _irq_enable(irq, 1);
+ if((unsigned)irq < NR_IRQS)
+ {
+ _irq_enable(irq, 1);
+ }
}
/****************************************************************************
@@ -243,18 +269,22 @@ void up_enable_irq(int irq)
#ifndef CONFIG_ARCH_IRQPRIO
int up_prioritize_irq(int nr, int prio)
{
- uint16_t val;
+ uint16_t val;
- if (prio == -1)
- prio = default_irq_prio[nr];
+ if (prio == -1)
+ {
+ prio = default_irq_prio[nr];
+ }
- if (prio > 31)
- prio = 31;
+ if (prio > 31)
+ {
+ prio = 31;
+ }
- val = prio << 2;
- putreg16(val, IRQ_REG(ILR_IRQ(nr)));
+ val = prio << 2;
+ putreg16(val, IRQ_REG(ILR_IRQ(nr)));
- return 0; // XXX: what's the return???
+ return 0;
}
#endif
@@ -264,25 +294,28 @@ int up_prioritize_irq(int nr, int prio)
void up_decodeirq(uint32_t *regs)
{
- uint8_t num, tmp;
- uint32_t *saved_regs;
+ uint8_t num, tmp;
+ uint32_t *saved_regs;
+
+ /* XXX: What is this???
+ * Passed to but ignored in IRQ handlers
+ * Only valid meaning is apparently non-NULL == IRQ context */
- /* XXX: What is this???
- * Passed to but ignored in IRQ handlers
- * Only valid meaning is apparently non-NULL == IRQ context */
- saved_regs = (uint32_t *)current_regs;
- current_regs = regs;
+ saved_regs = (uint32_t *)current_regs;
+ current_regs = regs;
- /* Detect & deliver the IRQ */
- num = getreg8(IRQ_REG(IRQ_NUM)) & 0x1f;
- irq_dispatch(num, regs);
+ /* Detect & deliver the IRQ */
- /* Start new IRQ agreement */
- tmp = getreg8(IRQ_REG(IRQ_CTRL));
- tmp |= 0x01;
- putreg8(tmp, IRQ_REG(IRQ_CTRL));
+ num = getreg8(IRQ_REG(IRQ_NUM)) & 0x1f;
+ irq_dispatch(num, regs);
- current_regs = saved_regs;
+ /* Start new IRQ agreement */
+
+ tmp = getreg8(IRQ_REG(IRQ_CTRL));
+ tmp |= 0x01;
+ putreg8(tmp, IRQ_REG(IRQ_CTRL));
+
+ current_regs = saved_regs;
}
/****************************************************************************
@@ -291,23 +324,26 @@ void up_decodeirq(uint32_t *regs)
void calypso_fiq(void)
{
- uint8_t num, tmp;
- uint32_t *regs;
+ uint8_t num, tmp;
+ uint32_t *regs;
+
+ /* XXX: What is this???
+ * Passed to but ignored in IRQ handlers
+ * Only valid meaning is apparently non-NULL == IRQ context */
+
+ regs = (uint32_t *)current_regs;
+ current_regs = (uint32_t *)&num;
+
+ /* Detect & deliver like an IRQ but we are in FIQ context */
- /* XXX: What is this???
- * Passed to but ignored in IRQ handlers
- * Only valid meaning is apparently non-NULL == IRQ context */
- regs = (uint32_t *)current_regs;
- current_regs = (uint32_t *)&num;
+ num = getreg8(IRQ_REG(FIQ_NUM)) & 0x1f;
+ irq_dispatch(num, regs);
- /* Detect & deliver like an IRQ but we are in FIQ context */
- num = getreg8(IRQ_REG(FIQ_NUM)) & 0x1f;
- irq_dispatch(num, regs);
+ /* Start new FIQ agreement */
- /* Start new FIQ agreement */
- tmp = getreg8(IRQ_REG(IRQ_CTRL));
- tmp |= 0x02;
- putreg8(tmp, IRQ_REG(IRQ_CTRL));
+ tmp = getreg8(IRQ_REG(IRQ_CTRL));
+ tmp |= 0x02;
+ putreg8(tmp, IRQ_REG(IRQ_CTRL));
- current_regs = regs;
+ current_regs = regs;
}
diff --git a/nuttx/arch/arm/src/calypso/calypso_keypad.c b/nuttx/arch/arm/src/calypso/calypso_keypad.c
index cdc22b286..141a20ab1 100644
--- a/nuttx/arch/arm/src/calypso/calypso_keypad.c
+++ b/nuttx/arch/arm/src/calypso/calypso_keypad.c
@@ -48,6 +48,7 @@
#include <arch/calypso/defines.h>
#include <arch/calypso/memory.h>
#include <arch/calypso/timer.h>
+#include <arch/calypso/armio.h>
/****************************************************************************
* HW access
diff --git a/nuttx/arch/arm/src/calypso/calypso_spi.c b/nuttx/arch/arm/src/calypso/calypso_spi.c
index d412fe791..8c7db775d 100644
--- a/nuttx/arch/arm/src/calypso/calypso_spi.c
+++ b/nuttx/arch/arm/src/calypso/calypso_spi.c
@@ -40,6 +40,7 @@
#include <nuttx/config.h>
#include <nuttx/spi.h>
+#include <unistd.h>
#include <debug.h>
#include "up_arch.h"
@@ -55,11 +56,11 @@ extern int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din
struct calypso_spidev_s
{
- struct spi_dev_s spidev; /* External driver interface */
- int nbits; /* Number of transfered bits */
+ struct spi_dev_s spidev; /* External driver interface */
+ int nbits; /* Number of transfered bits */
#ifndef CONFIG_SPI_OWNBUS
- sem_t exclsem; /* Mutual exclusion of devices */
+ sem_t exclsem; /* Mutual exclusion of devices */
#endif
};
@@ -69,13 +70,13 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
#endif
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
- bool selected)
+ bool selected)
{
}
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
{
- return frequency;
+ return frequency;
}
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
@@ -83,26 +84,29 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
}
/* Osmocom wrapper */
+
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
{
- ((FAR struct calypso_spidev_s *)dev)->nbits = nbits;
+ ((FAR struct calypso_spidev_s *)dev)->nbits = nbits;
}
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
- FAR void *rxbuffer, size_t nwords)
+ FAR void *rxbuffer, size_t nwords)
{
- FAR struct calypso_spidev_s *priv = (FAR struct calypso_spidev_s *)dev;
- size_t i;
+ FAR struct calypso_spidev_s *priv = (FAR struct calypso_spidev_s *)dev;
+ size_t i;
- for(i=0; i<nwords; i++)
- spi_xfer(0, priv->nbits, txbuffer+i, rxbuffer+i);
+ for (i = 0; i < nwords; i++)
+ {
+ spi_xfer(0, priv->nbits, txbuffer+i, rxbuffer+i);
+ }
}
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
{
- uint16_t buf = wd;
- spi_exchange(dev, &buf, &buf, 1);
- return buf;
+ uint16_t buf = wd;
+ spi_exchange(dev, &buf, &buf, 1);
+ return buf;
}
static const struct spi_ops_s g_spiops =
@@ -130,103 +134,143 @@ static const struct spi_ops_s g_spiops =
static struct calypso_spidev_s g_spidev =
{
- .spidev = { &g_spiops },
- .nbits = 0,
+ .spidev = { &g_spiops },
+ .nbits = 0,
};
void spi_init(void)
{
- putreg16(SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | SPI_SET1_RDWR_IRQ_DIS,
- SPI_REG(REG_SET1));
+ putreg16(SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | SPI_SET1_RDWR_IRQ_DIS,
+ SPI_REG(REG_SET1));
- putreg16(0x0001, SPI_REG(REG_SET2));
+ putreg16(0x0001, SPI_REG(REG_SET2));
}
int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din)
{
- uint8_t bytes_per_xfer;
- uint8_t reg_status, reg_ctrl = 0;
- uint32_t tmp;
-
- if (bitlen == 0)
- return 0;
-
- if (bitlen > 32)
- return -1;
-
- if (dev_idx > 4)
- return -1;
-
- bytes_per_xfer = bitlen / 8;
- if (bitlen % 8)
- bytes_per_xfer ++;
-
- reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT;
- reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT;
-
- if (bitlen <= 8) {
- tmp = *(uint8_t *)dout;
- tmp <<= 24 + (8-bitlen); /* align to MSB */
- } else if (bitlen <= 16) {
- tmp = *(uint16_t *)dout;
- tmp <<= 16 + (16-bitlen); /* align to MSB */
- } else {
- tmp = *(uint32_t *)dout;
- tmp <<= (32-bitlen); /* align to MSB */
- }
- dbg("spi_xfer(dev_idx=%u, bitlen=%u, data_out=0x%08x): ",
- dev_idx, bitlen, tmp);
-
- /* fill transmit registers */
- putreg16(tmp >> 16, SPI_REG(REG_TX_MSB));
- putreg16(tmp & 0xffff, SPI_REG(REG_TX_LSB));
-
- /* initiate transfer */
- if (din)
- reg_ctrl |= SPI_CTRL_RDWR;
- else
- reg_ctrl |= SPI_CTRL_WR;
- putreg16(reg_ctrl, SPI_REG(REG_CTRL));
- dbg("reg_ctrl=0x%04x ", reg_ctrl);
-
- /* wait until the transfer is complete */
- while (1) {
- reg_status = getreg16(SPI_REG(REG_STATUS));
- dbg("status=0x%04x ", reg_status);
- if (din && (reg_status & SPI_STATUS_RE))
- break;
- else if (reg_status & SPI_STATUS_WE)
- break;
- }
- /* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */
- usleep(1000);
-
- if (din) {
- tmp = getreg16(SPI_REG(REG_RX_MSB)) << 16;
- tmp |= getreg16(SPI_REG(REG_RX_LSB));
- dbg("data_in=0x%08x ", tmp);
-
- if (bitlen <= 8)
- *(uint8_t *)din = tmp & 0xff;
- else if (bitlen <= 16)
- *(uint16_t *)din = tmp & 0xffff;
- else
- *(uint32_t *)din = tmp;
- }
- dbg("\n");
-
- return 0;
+ uint8_t bytes_per_xfer;
+ uint8_t reg_status, reg_ctrl = 0;
+ uint32_t tmp;
+
+ if (bitlen == 0)
+ {
+ return 0;
+ }
+
+ if (bitlen > 32)
+ {
+ return -1;
+ }
+
+ if (dev_idx > 4)
+ {
+ return -1;
+ }
+
+ bytes_per_xfer = bitlen / 8;
+ if (bitlen % 8)
+ {
+ bytes_per_xfer ++;
+ }
+
+ reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT;
+ reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT;
+
+ if (bitlen <= 8)
+ {
+ tmp = *(uint8_t *)dout;
+ tmp <<= 24 + (8-bitlen); /* align to MSB */
+ }
+ else if (bitlen <= 16)
+ {
+ tmp = *(uint16_t *)dout;
+ tmp <<= 16 + (16-bitlen); /* align to MSB */
+ }
+ else
+ {
+ tmp = *(uint32_t *)dout;
+ tmp <<= (32-bitlen); /* align to MSB */
+ }
+
+ dbg("spi_xfer(dev_idx=%u, bitlen=%u, data_out=0x%08x): ",
+ dev_idx, bitlen, tmp);
+
+ /* fill transmit registers */
+
+ putreg16(tmp >> 16, SPI_REG(REG_TX_MSB));
+ putreg16(tmp & 0xffff, SPI_REG(REG_TX_LSB));
+
+ /* initiate transfer */
+
+ if (din)
+ {
+ reg_ctrl |= SPI_CTRL_RDWR;
+ }
+ else
+ {
+ reg_ctrl |= SPI_CTRL_WR;
+ }
+
+ putreg16(reg_ctrl, SPI_REG(REG_CTRL));
+ dbg("reg_ctrl=0x%04x ", reg_ctrl);
+
+ /* wait until the transfer is complete */
+
+ while (1)
+ {
+ reg_status = getreg16(SPI_REG(REG_STATUS));
+ dbg("status=0x%04x ", reg_status);
+ if (din && (reg_status & SPI_STATUS_RE))
+ {
+ break;
+ }
+ else if (reg_status & SPI_STATUS_WE)
+ {
+ break;
+ }
+ }
+
+ /* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */
+
+ usleep(1000);
+
+ if (din)
+ {
+ tmp = getreg16(SPI_REG(REG_RX_MSB)) << 16;
+ tmp |= getreg16(SPI_REG(REG_RX_LSB));
+ dbg("data_in=0x%08x ", tmp);
+
+ if (bitlen <= 8)
+ {
+ *(uint8_t *)din = tmp & 0xff;
+ }
+ else if (bitlen <= 16)
+ {
+ *(uint16_t *)din = tmp & 0xffff;
+ }
+ else
+ {
+ *(uint32_t *)din = tmp;
+ }
+ }
+
+ dbg("\n");
+
+ return 0;
}
FAR struct spi_dev_s *up_spiinitialize(int port)
{
- switch(port) {
- case 0: /* SPI master device */
- spi_init();
- return (FAR struct spi_dev_s *)&g_spidev;
- case 1: /* uWire device */
- return NULL;
- default:
- return NULL;
- }
+ switch (port)
+ {
+ case 0: /* SPI master device */
+ spi_init();
+ return (FAR struct spi_dev_s *)&g_spidev;
+
+ case 1: /* uWire device */
+ return NULL;
+
+ default:
+ return NULL;
+ }
}