Add SPI method to set SCLK mode

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1669 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-03-29 21:14:34 +00:00
parent 7b487e8dc9
commit eb7cadce8f
7 changed files with 102 additions and 16 deletions

View File

@ -686,3 +686,5 @@
* Add an enumeration argument to the SPI chip select and status methods so
that the interface can handle more than one device.
* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
* Add a setmode() method to the SPI interface to handle parts with differing
mode requirements.

View File

@ -1359,6 +1359,8 @@ nuttx-0.4.5 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* Add an enumeration argument to the SPI chip select and status methods so
that the interface can handle more than one device.
* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
* Add a setmode() method to the SPI interface to handle parts with differing
mode requirements.
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -66,6 +66,7 @@
****************************************************************************/
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@ -78,6 +79,7 @@ static const struct spi_ops_s g_spiops =
{
ez80_spiselect, /* Provided externally by board logic */
spi_setfrequency,
spi_setmode,
ez80_spistatus, /* Provided externally by board logic */
spi_sndbyte,
spi_sndblock,
@ -148,6 +150,58 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
return ((EZ80_SYS_CLK_FREQ+1)/2 + brg - 1) / brg;
}
/****************************************************************************
* Name: spi_setmode
*
* Description:
* Set the SPI mode. Optional. See enum spi_mode_e for mode definitions
*
* Input Parameters:
* dev - Device-specific state data
* mode - The SPI mode requested
*
* Returned Value:
* none
*
****************************************************************************/
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
{
ubyte modebits;
ubyte regval;
/* Select the CTL register bits based on the selected mode */
switch (mode)
{
case SPIDEV_MODE0: /* CPOL=0 CHPHA=0 */
modebits = 0;
break;
case SPIDEV_MODE1: /* CPOL=0 CHPHA=1 */
modebits = SPI_CTL_CPHA;
break;
case SPIDEV_MODE2: /* CPOL=1 CHPHA=0 */
modebits = SPI_CTL_CPOL;
break;
case SPIDEV_MODE3: /* CPOL=1 CHPHA=1 */
modebits = (SPI_CTL_CPOL|SPI_CTL_CPHA);
break;
default:
return;
}
/* Then set those bits in the CTL register */
regval = inp(EZ80_SPI_CTL);
regval &= ~(SPI_CTL_CPOL|SPI_CTL_CPHA);
regval |= modebits;
outp(EZ80_SPI_CTL, regval);
}
/****************************************************************************
* Name: spi_waitspif
*
@ -367,7 +421,7 @@ FAR struct spi_dev_s *up_spiinitialize(int port)
/* Enable the SPI.
* NOTE 1: Interrupts are not used in this driver version.
* NOTE 2: Certain devices may need changes to SCK polarity settings.
* NOTE 2: Initial mode is mode=0.
*/
outp(EZ80_SPI_CTL, SPI_CTL_SPIEN|SPI_CTL_MASTEREN);

View File

@ -113,8 +113,8 @@ extern "C" {
* will bind the SPI driver to the SPI MMC/SD driver.
*/
EXTERN void ez80_spiselect(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
EXTERN ubyte ez80_spistatus(FAR struct spi_dev_s *dev, enum spidev_e devid);
EXTERN void ez80_spiselect(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
EXTERN ubyte ez80_spistatus(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
#undef EXTERN
#ifdef __cplusplus

View File

@ -86,9 +86,9 @@
* Private Function Prototypes
****************************************************************************/
static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@ -135,7 +135,7 @@ static struct spi_dev_s g_spidev = { &g_spiops };
*
****************************************************************************/
static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected)
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected)
{
uint32 bit = 1 << 20;
@ -222,7 +222,7 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
*
****************************************************************************/
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid)
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
{
/* I don't think there is anyway to determine these things on the mcu123.com
* board.

View File

@ -263,9 +263,9 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset,
/* SPI methods */
static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid);
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch);
static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);
@ -369,7 +369,7 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset, ui
*
****************************************************************************/
static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected)
static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected)
{
FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev;
uint16 reg16;
@ -499,7 +499,7 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
*
****************************************************************************/
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spidev_e devid)
static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
{
ubyte ret = 0;
uint16 reg16 = getreg16(STR71X_GPIO1_PD);

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/usbdev/spi.h
* include/nuttx/spi.h
*
* Copyright(C) 2008 Gregory Nutt. All rights reserved.
* Copyright(C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@ -87,6 +87,23 @@
#define SPI_SETFREQUENCY(d,f) ((d)->ops->setfrequency(d,f))
/****************************************************************************
* Name: SPI_SETMODE
*
* Description:
* Set the SPI mode. Optional. See enum spi_mode_e for mode definitions
*
* Input Parameters:
* dev - Device-specific state data
* mode - The SPI mode requested
*
* Returned Value:
* none
*
****************************************************************************/
#define SPI_SETMODE(d,m) ((d)->ops->mode(d,m))
/****************************************************************************
* Name: SPI_STATUS
*
@ -198,21 +215,32 @@ typedef void (*mediachange_t)(void *arg);
* which is selected or de-seleted.
*/
enum spidev_e
enum spi_dev_e
{
SPIDEV_NONE = 0, /* Not a valid value */
SPIDEV_MMCSD, /* Select SPI MMC/SD device */
SPIDEV_ETHERNET /* Select SPI ethernet device */
};
/* Certain SPI devices may required differnt clocking modes */
enum spi_mode_e
{
SPIDEV_MODE0 = 0, /* CPOL=0 CHPHA=0 */
SPIDEV_MODE1, /* CPOL=0 CHPHA=1 */
SPIDEV_MODE2, /* CPOL=1 CHPHA=0 */
SPIDEV_MODE3 /* CPOL=1 CHPHA=1 */
};
/* The SPI vtable */
struct spi_dev_s;
struct spi_ops_s
{
void (*select)(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected);
void (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean selected);
uint32 (*setfrequency)(FAR struct spi_dev_s *dev, uint32 frequency);
ubyte (*status)(FAR struct spi_dev_s *dev, enum spidev_e devid);
void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
ubyte (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid);
ubyte (*sndbyte)(FAR struct spi_dev_s *dev, ubyte ch);
void (*sndblock)(FAR struct spi_dev_s *dev, FAR const ubyte *buffer, size_t buflen);
void (*recvblock)(FAR struct spi_dev_s *dev, FAR ubyte *buffer, size_t buflen);