From abcc509bf98d1a87b05ee17dffa700ffaacaf30b Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 15 May 2010 01:15:52 +0000 Subject: In progress changes for OLED display work git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2669 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/ChangeLog | 4 +- nuttx/Documentation/NuttX.html | 6 +- nuttx/Documentation/NuttxPortingGuide.html | 73 ++++++++++++++- nuttx/TODO | 9 +- nuttx/arch/arm/src/imx/imx_spi.c | 39 +++++++- nuttx/arch/arm/src/lm3s/lm3s_ssi.c | 37 +++++++- nuttx/arch/arm/src/stm32/stm32_spi.c | 16 +++- nuttx/arch/z80/src/ez80/ez80_spi.c | 39 +++++++- nuttx/configs/README.txt | 30 ++++++ nuttx/configs/mcu123-lpc214x/src/up_spi.c | 39 +++++++- nuttx/configs/olimex-strp711/nettest/defconfig | 4 - nuttx/configs/olimex-strp711/src/up_spi.c | 37 +++++++- nuttx/drivers/lcd/p14201.c | 122 ++++++++++++++++++++++--- nuttx/drivers/net/enc28j60.c | 17 ++-- nuttx/examples/nx/nx_kbdin.c | 12 ++- nuttx/include/nuttx/enc28j60.h | 3 - nuttx/include/nuttx/p14201.h | 11 ++- nuttx/include/nuttx/spi.h | 19 +++- 18 files changed, 464 insertions(+), 53 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 571e336ca..8ed09d3ef 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1126,4 +1126,6 @@ 5.6 2010-xx-xx Gregory Nutt - * drivers/lcd/p14201.c - Driver for RiT P14201 series OLED. + * drivers/lcd/p14201.c - Driver for RiT P14201 series 128x96 4-bit OLED. + * configs/lm3s6965-ek/nx - NX graphics configuration for the LM3S6965 + Ethernet Evaluation Kit. diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index e454ffd39..05b31b4b1 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -8,7 +8,7 @@

NuttX RTOS

-

Last Updated: May 10, 2010

+

Last Updated: May 12, 2010

@@ -1749,7 +1749,9 @@ buildroot-1.8 2009-12-21 <spudmonkey@racsa.co.cr> -

SPI-based MMC/SD driver

+

Device Drivers

+

SPI driver

+ + +

SPI-based MMC/SD driver

  • CONFIG_MMCSD_NSLOTS: Number of MMC/SD slots supported by the driver. Default is one. @@ -2496,7 +2510,7 @@ extern void up_ledoff(int led);
-

SDIO-based MMC/SD driver

+

SDIO-based MMC/SD driver

  • CONFIG_FS_READAHEAD: Enable read-ahead buffering @@ -2515,8 +2529,59 @@ extern void up_ledoff(int led);
+

RiT P14201 OLED driver

+
    +
  • + CONFIG_LCD_P14201: Enable P14201 support +
  • +
  • + CONFIG_P14201_SPIMODE: Controls the SPI mode +
  • +
  • + CONFIG_P14201_FREQUENCY: Define to use a different bus frequency +
  • +
  • + CONFIG_P14201_NINTERFACES: + Specifies the number of physical P14201 devices that will be supported. +
  • +
  • + CONFIG_P14201_FRAMEBUFFER: + If defined, accesses will be performed using an in-memory copy of the OLEDs GDDRAM. + This cost of this buffer is 128 * 96 / 2 = 6Kb. + If this is defined, then the driver will be fully functioned. + If not, then it will have the following limitations: +
      +
    • Reading graphics memory cannot be supported, and
    • +
    • All pixel writes must be aligned to byte boundaries.
    • +
    +
  • +
+ +

ENC28J60 Ethernet Driver Configuration Settings

+
    +
  • + CONFIG_NET_ENC28J60: Enabled ENC28J60 support +
  • +
  • + CONFIG_ENC28J60_SPIMODE: Controls the SPI mode +
  • +
  • + CONFIG_ENC28J60_FREQUENCY: Define to use a different bus frequency +
  • +
  • + CONFIG_ENC28J60_NINTERFACES: + Specifies the number of physical ENC28J60 devices that will be supported. +
  • +
  • + CONFIG_ENC28J60_STATS: Collect network statistics +
  • +
  • + CONFIG_ENC28J60_HALFDUPPLEX: Default is full duplex +
  • +
+

Network Support

-

TCP/IP and UDP support via uIP

+

TCP/IP and UDP support via uIP

  • CONFIG_NET: Enable or disable all network features diff --git a/nuttx/TODO b/nuttx/TODO index 2afd1d490..87dd3ed89 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated May 8, 2010) +NuttX TODO List (Last updated May 14, 2010) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (5) Task/Scheduler (sched/) @@ -11,7 +11,7 @@ NuttX TODO List (Last updated May 8, 2010) (5) Network Utilities (netutils/) (1) USB (drivers/usbdev) (5) Libraries (lib/) - (11) File system/Generic drivers (fs/, drivers/) + (12) File system/Generic drivers (fs/, drivers/) (3) Graphics subystem (graphics/) (1) Pascal add-on (pcode/) (1) Documentation (Documentation/) @@ -409,6 +409,11 @@ o File system / Generic drivers (fs/, drivers/) Status: Open Priority: Low + Description: ENC28J60 driver is complete, but untested (I still haven't got + a good ENC28J60 test platform). + Status: Open + Priority: Low + o Graphics subystem (graphics/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/nuttx/arch/arm/src/imx/imx_spi.c b/nuttx/arch/arm/src/imx/imx_spi.c index 0a7ca9af0..578e274cd 100755 --- a/nuttx/arch/arm/src/imx/imx_spi.c +++ b/nuttx/arch/arm/src/imx/imx_spi.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/imx/imx_spi.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -166,6 +166,9 @@ static int spi_interrupt(int irq, void *context); /* SPI methods */ +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +#endif static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); @@ -186,7 +189,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t static const struct spi_ops_s g_spiops = { - .lock = 0, /* Not yet implemented */ +#ifndef CONFIG_SPI_OWNBUS + .lock = spi_lock, +#endif .select = imx_spiselect, /* Provided externally by board logic */ .setfrequency = spi_setfrequency, .setmode = spi_setmode, @@ -672,6 +677,36 @@ static int spi_interrupt(int irq, void *context) } #endif +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + /* Not implemented */ + + return -ENOSYS; +} +#endif + /**************************************************************************** * Name: spi_setfrequency * diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c index bbe04bd1b..73b995671 100755 --- a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c +++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c @@ -232,6 +232,9 @@ static int ssi_interrupt(int irq, void *context); /* SPI methods */ +#ifndef CONFIG_SPI_OWNBUS +static int ssi_lock(FAR struct spi_dev_s *dev, bool lock); +#endif static void ssi_setfrequencyinternal(struct lm3s_ssidev_s *priv, uint32_t frequency); static uint32_t ssi_setfrequency(FAR struct spi_dev_s *dev, @@ -260,7 +263,9 @@ static void ssi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, static const struct spi_ops_s g_spiops = { - .lock = 0, /* Not yet implemented */ +#ifndef CONFIG_SPI_OWNBUS + .lock = ssi_lock, +#endif .select = lm3s_spiselect, /* Provided externally by board logic */ .setfrequency = ssi_setfrequency, .setmode = ssi_setmode, @@ -968,6 +973,36 @@ static int ssi_interrupt(int irq, void *context) } #endif +/**************************************************************************** + * Name: ssi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int ssi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + /* Not implemented */ + + return -ENOSYS; +} +#endif + /**************************************************************************** * Name: ssi_setfrequency * diff --git a/nuttx/arch/arm/src/stm32/stm32_spi.c b/nuttx/arch/arm/src/stm32/stm32_spi.c index de0ff2ac5..4b50380eb 100755 --- a/nuttx/arch/arm/src/stm32/stm32_spi.c +++ b/nuttx/arch/arm/src/stm32/stm32_spi.c @@ -1,7 +1,7 @@ /************************************************************************************ * arm/arm/src/stm32/stm32_spi.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -137,7 +137,9 @@ struct stm32_spidev_s sem_t rxsem; /* Wait for RX DMA to complete */ sem_t txsem; /* Wait for TX DMA to complete */ #endif +#ifndef CONFIG_SPI_OWNBUS sem_t exclsem; /* Held while chip is selected for mutual exclusion */ +#endif }; /************************************************************************************ @@ -172,7 +174,9 @@ static inline void spi_dmatxstart(FAR struct stm32_spidev_s *priv); /* SPI methods */ +#ifndef CONFIG_SPI_OWNBUS static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +#endif static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); static void spi_setbits(FAR struct spi_dev_s *dev, int nbits); @@ -197,7 +201,9 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv); #ifdef CONFIG_STM32_SPI1 static const struct spi_ops_s g_sp1iops = { +#ifndef CONFIG_SPI_OWNBUS .lock = spi_lock, +#endif .select = stm32_spi1select, .setfrequency = spi_setfrequency, .setmode = spi_setmode, @@ -231,7 +237,9 @@ static struct stm32_spidev_s g_spi1dev = #ifdef CONFIG_STM32_SPI2 static const struct spi_ops_s g_sp2iops = { +#ifndef CONFIG_SPI_OWNBUS .lock = spi_lock, +#endif .select = stm32_spi2select, .setfrequency = spi_setfrequency, .setmode = spi_setmode, @@ -265,7 +273,9 @@ static struct stm32_spidev_s g_spi2dev = #ifdef CONFIG_STM32_SPI3 static const struct spi_ops_s g_sp3iops = { +#ifndef CONFIG_SPI_OWNBUS .lock = spi_lock, +#endif .select = stm32_spi3select, .setfrequency = spi_setfrequency, .setmode = spi_setmode, @@ -694,6 +704,7 @@ static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits, uin * ****************************************************************************/ +#ifndef CONFIG_SPI_OWNBUS static int spi_lock(FAR struct spi_dev_s *dev, bool lock) { FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev; @@ -717,6 +728,7 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock) } return OK; } +#endif /************************************************************************************ * Name: spi_setfrequency @@ -1185,7 +1197,9 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv) /* Initialize the SPI semaphore that enforces mutually exclusive access */ +#ifndef CONFIG_SPI_OWNBUS sem_init(&priv->exclsem, 0, 1); +#endif /* Initialize the SPI semaphores that is used to wait for DMA completion */ diff --git a/nuttx/arch/z80/src/ez80/ez80_spi.c b/nuttx/arch/z80/src/ez80/ez80_spi.c index 6c5f7f2aa..22cfd789c 100755 --- a/nuttx/arch/z80/src/ez80/ez80_spi.c +++ b/nuttx/arch/z80/src/ez80/ez80_spi.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/z80/src/ez80/ez80_spi.c * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -67,6 +67,9 @@ * Private Function Prototypes ****************************************************************************/ +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock); +#endif static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode); @@ -82,7 +85,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR uint8_t *buffer, static const struct spi_ops_s g_spiops = { - 0, /* lock() method not yet implemented */ +#ifndef CONFIG_SPI_OWNBUS + spi_lock, +#endif ez80_spiselect, /* Provided externally by board logic */ spi_setfrequency, spi_setmode, @@ -109,6 +114,36 @@ static struct spi_dev_s g_spidev = { &g_spiops }; * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + /* Not implemented */ + + return -ENOSYS; +} +#endif + /**************************************************************************** * Name: spi_setfrequency * diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index 9eed9da0c..6eae21fcf 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -327,6 +327,13 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_FAT_SECTORSIZE - Max supported sector size CONFIG_FS_ROMFS - Enable ROMFS filesystem support + SPI driver + CONFIG_SPI_OWNBUS - Set if there is only one active device + on the SPI bus. No locking or SPI configuration will be performed. + It is not necessary for clients to lock, re-configure, etc.. + CONFIG_SPI_EXCHANGE - Driver supports a single exchange method + (vs a recvblock() and sndblock ()methods) + SPI-based MMC/SD driver CONFIG_MMCSD_NSLOTS - Number of MMC/SD slots supported by the driver. Default is one. @@ -343,6 +350,29 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_MMCSD_HAVECARDDETECT - SDIO driver card detection is 100% accurate + RiT P14201 OLED driver + CONFIG_LCD_P14201 - Enable P14201 support + CONFIG_P14201_SPIMODE - Controls the SPI mode + CONFIG_P14201_FREQUENCY - Define to use a different bus frequency + CONFIG_P14201_NINTERFACES - Specifies the number of physical P14201 + devices that will be supported. + CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed + using an in-memory copy of the OLEDs GDDRAM. This cost of this + buffer is 128 * 96 / 2 = 6Kb. If this is defined, then the driver + will be fully functioned. If not, then it will have the following + limitations: + - Reading graphics memory cannot be supported, and + - All pixel writes must be aligned to byte boundaries. + + ENC28J60 Ethernet Driver Configuration Settings: + CONFIG_NET_ENC28J60 - Enabled ENC28J60 support + CONFIG_ENC28J60_SPIMODE - Controls the SPI mode + CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency + CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 + devices that will be supported. + CONFIG_ENC28J60_STATS - Collect network statistics + CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex + TCP/IP and UDP support via uIP CONFIG_NET - Enable or disable all network features CONFIG_NET_IPv6 - Build in support for IPv6 diff --git a/nuttx/configs/mcu123-lpc214x/src/up_spi.c b/nuttx/configs/mcu123-lpc214x/src/up_spi.c index f9949a7ea..d8ae8baf8 100644 --- a/nuttx/configs/mcu123-lpc214x/src/up_spi.c +++ b/nuttx/configs/mcu123-lpc214x/src/up_spi.c @@ -2,7 +2,7 @@ * config/mcu123-lpc214x/src/up_spi.c * arch/arm/src/board/up_spi.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -123,6 +123,9 @@ * Private Function Prototypes ****************************************************************************/ +#ifndef CONFIG_SPI_OWNBUS +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); static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); @@ -136,7 +139,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t static const struct spi_ops_s g_spiops = { - .lock = 0, /* Not yet implemented */ +#ifndef CONFIG_SPI_OWNBUS + .lock = spi_lock, +#endif .select = spi_select, .setfrequency = spi_setfrequency, .status = spi_status, @@ -156,6 +161,36 @@ static struct spi_dev_s g_spidev = { &g_spiops }; * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + /* Not implemented */ + + return -ENOSYS; +} +#endif + /**************************************************************************** * Name: spi_select * diff --git a/nuttx/configs/olimex-strp711/nettest/defconfig b/nuttx/configs/olimex-strp711/nettest/defconfig index 256f81665..89a638d3e 100755 --- a/nuttx/configs/olimex-strp711/nettest/defconfig +++ b/nuttx/configs/olimex-strp711/nettest/defconfig @@ -432,9 +432,6 @@ CONFIG_FS_ROMFS=n # ENC28J60 configuration # # CONFIG_NET_ENC28J60 - Enabled ENC28J60 support -# CONFIG_ENC28J60_OWNBUS - Set if the ENC28J60 is the only active device on -# the SPI bus. No locking or SPI configuration will be performed. All -# transfers will be performed from the ENC2J60 interrupt handler. # CONFIG_ENC28J60_SPIMODE - Controls the SPI mode # CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency # CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 @@ -442,7 +439,6 @@ CONFIG_FS_ROMFS=n # CONFIG_ENC28J60_STATS - Collect network statistics # CONFOG_ENC28J60_HALFDUPPLEX - Default is full duplex CONFIG_NET_ENC28J60=y -CONFIG_ENC28J60_OWNBUS=n #CONFIG_ENC28J60_SPIMODE CONFIG_ENC28J60_FREQUENCY=20000000 CONFIG_ENC28J60_NINTERFACES=1 diff --git a/nuttx/configs/olimex-strp711/src/up_spi.c b/nuttx/configs/olimex-strp711/src/up_spi.c index c01cbbc87..5ca35b72e 100644 --- a/nuttx/configs/olimex-strp711/src/up_spi.c +++ b/nuttx/configs/olimex-strp711/src/up_spi.c @@ -390,6 +390,9 @@ static inline void spi_drain(FAR struct str71x_spidev_s *priv); /* SPI methods */ +#ifndef CONFIG_SPI_OWNBUS +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); static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency); static uint8_t spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid); @@ -403,7 +406,9 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t static const struct spi_ops_s g_spiops = { - .lock = 0, /* Not yet implemented */ +#ifndef CONFIG_SPI_OWNBUS + .lock = spi_lock, +#endif .select = spi_select, .setfrequency = spi_setfrequency, .status = spi_status, @@ -526,6 +531,36 @@ static inline void spi_drain(FAR struct str71x_spidev_s *priv) while ((spi_getreg(priv, STR71X_BSPI_CSR2_OFFSET) & STR71X_BSPICSR2_RFNE) != 0); } +/**************************************************************************** + * Name: spi_lock + * + * Description: + * On SPI busses where there are multiple devices, it will be necessary to + * lock SPI to have exclusive access to the busses for a sequence of + * transfers. The bus should be locked before the chip is selected. After + * locking the SPI bus, the caller should then also call the setfrequency, + * setbits, and setmode methods to make sure that the SPI is properly + * configured for the device. If the SPI buss is being shared, then it + * may have been left in an incompatible state. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock spi bus, false: unlock SPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static int spi_lock(FAR struct spi_dev_s *dev, bool lock) +{ + /* Not implemented */ + + return -ENOSYS; +} +#endif + /**************************************************************************** * Name: spi_select * diff --git a/nuttx/drivers/lcd/p14201.c b/nuttx/drivers/lcd/p14201.c index bc78ffb8a..73e303979 100755 --- a/nuttx/drivers/lcd/p14201.c +++ b/nuttx/drivers/lcd/p14201.c @@ -65,13 +65,17 @@ /* P14201 Configuration Settings: * * CONFIG_LCD_P14201 - Enable P14201 support - * CONFIG_P14201_OWNBUS - Set if the P14201 is the only active device on the SPI bus. - * No locking or SPI configuration will be performed. All transfers will be performed - * from the ENC2J60 interrupt handler. * CONFIG_P14201_SPIMODE - Controls the SPI mode * CONFIG_P14201_FREQUENCY - Define to use a different bus frequency * CONFIG_P14201_NINTERFACES - Specifies the number of physical P14201 devices that * will be supported. + * CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory + * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 96 / 2 = 6Kb. If this + * is defined, then the driver will be fully functioned. If not, then it will have the + * following limitations: + * + * - Reading graphics memory cannot be supported, and + * - All pixel writes must be aligned to byte boundaries. * * Required LCD driver settings: * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. @@ -149,7 +153,7 @@ /* Default contrast */ -#define RIT_CONTRAST 183 /* 183/255 */ +#define RIT_CONTRAST ((23 * (CONFIG_LCD_MAXCONTRAST+1) / 32) - 1) /* Helper Macros **********************************************************************/ @@ -185,7 +189,7 @@ struct rit_dev_s /* Low-level SPI helpers */ static inline void rit_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_P14201_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void rit_select(FAR struct spi_dev_s *spi); static inline void rit_deselect(FAR struct spi_dev_s *spi); #else @@ -244,7 +248,19 @@ static int rit_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); * if there are multiple LCD devices, they must each have unique run buffers. */ -static uint8_t g_runbuffer[CONFIG_P14201_NINTERFACES * RIT_XRES / 2]; +static uint8_t g_runbuffer[RIT_XRES / 2]; + +/* CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory + * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 64 / 2 = 4Kb. If this + * is defined, then the driver will be full functioned. If not, then: + * + * - Reading graphics memory cannot be supported, and + * - All pixel writes must be aligned to byte boundaries. + */ + +#ifdef CONFIG_P14201_FRAMEBUFFER +static uint8_t g_framebuffer[RIT_YRES * RIT_XRES / 2]; +#endif /* This structure describes the overall LCD video controller */ @@ -289,7 +305,6 @@ static struct rit_dev_s g_oleddev = }, }; - /* A table of magic initialization commands. This initialization sequence is * derived from RiT Application Note for the P14201 (with a few tweaked values * as discovered in some Luminary code examples). @@ -419,7 +434,7 @@ static inline void rit_configspi(FAR struct spi_dev_s *spi) * bother because it might change. */ -#ifdef CONFIG_P14201_OWNBUS +#ifdef CONFIG_SPI_OWNBUS SPI_SETMODE(spi, CONFIG_P14201_SPIMODE); SPI_SETBITS(spi, 8); #ifdef CONFIG_P14201_FREQUENCY @@ -444,7 +459,7 @@ static inline void rit_configspi(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_P14201_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void rit_select(FAR struct spi_dev_s *spi) { /* We own the SPI bus, so just select the chip */ @@ -489,7 +504,7 @@ static void rit_select(FAR struct spi_dev_s *spi) * **************************************************************************************/ -#ifdef CONFIG_P14201_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void rit_deselect(FAR struct spi_dev_s *spi) { /* We own the SPI bus, so just de-select the chip */ @@ -605,6 +620,26 @@ static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table) static inline void rit_clear(FAR struct rit_dev_s *priv) { +#ifdef CONFIG_P14201_FRAMEBUFFER + FAR uint8_t *ptr = g_framebuffer; + unsigned int row; + + /* Set a window to fill the entire display */ + + rit_sndcmd(priv, g_setallcol, sizeof(g_setallcol)); + rit_sndcmd(priv, g_setallrow, sizeof(g_setallrow)); + rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); + + /* Display each row */ + + for(row = 0; row < RIT_YRES; row++) + { + /* Display a horizontal run */ + + rit_snddata(priv, ptr, RIT_XRES / 2); + ptr += RIT_XRES / 2; + } +#else unsigned int row; /* Create a black row */ @@ -625,6 +660,7 @@ static inline void rit_clear(FAR struct rit_dev_s *priv) rit_snddata(priv, g_runbuffer, RIT_XRES / 2); } +#endif } /************************************************************************************** @@ -644,11 +680,63 @@ static inline void rit_clear(FAR struct rit_dev_s *priv) static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, size_t npixels) { +#ifdef CONFIG_P14201_FRAMEBUFFER FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev; uint8_t cmd[3]; + uint8_t *run; + int start; + int end; + int i; gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); + /* Get the starting and ending byte offsets containing the run */ + + start = col >> 1; + aend = (col + npixels) >> 1; + end = (col + npixels + 1) >> 1; + + /* Get the beginning of the run in the framebuffer */ + + run = g_framebuffer + row * RIT_XRES / 2 + start; + + /* Copy the run into the framebuffer, handling nibble alignment */ + + if ((col & 1) == 0) + { + /* Beginning of buffer is properly aligned */ + + memcpy(run, buffer, aend - start); + + /* Handle an final partial byte */ + + if (aend != end) + { + /* The leftmost column being contained in bits 7:4 */ +# warning "Missing logic" + } + } + else + { + /* Buffer is not byte aligned with display data. Each byte contains the + * data for two columns: The leftmost column being contained in bits + * 7:4 and the rightmost column being contained in bits 3:0. + */ + + for (i = 0; i < aend - start; i++) + { +# warning "Missing logic" + } + + } + + /* Then copy the (aligned) run from the framebuffer to the OLED */ +# warning "Missing logic" +#else + FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev; + uint8_t cmd[3]; + + gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); DEBUGASSERT(buffer); if (npixels > 0) { @@ -701,14 +789,18 @@ static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, size_t npixels) { - /* Buffer must be provided and aligned to a 16-bit address boundary */ - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); DEBUGASSERT(buffer); +#ifdef CONFIG_P14201_FRAMEBUFFER + /* Cant read from OLED GDDRAM in SPI mode, but we can read from the framebuffer */ + +# warning "Missing logic" +#else /* Can't read from OLED GDDRAM in SPI mode */ return -ENOSYS; +#endif } /************************************************************************************** @@ -886,6 +978,12 @@ FAR struct lcd_dev_s *rit_initialize(FAR struct spi_dev_s *spi, unsigned int dev priv->contrast = RIT_CONTRAST; priv->on = false; + /* Initialize the framebuffer */ + +#ifdef CONFIG_P14201_FRAMEBUFFER + memset(g_framebuffer, (RIT_Y4_BLACK << 4) | RIT_Y4_BLACK, RIT_YRES * RIT_XRES / 2); +#endif + /* Clear the display */ rit_clear(priv); diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c index 881b97393..1db44cef1 100755 --- a/nuttx/drivers/net/enc28j60.c +++ b/nuttx/drivers/net/enc28j60.c @@ -75,9 +75,6 @@ /* ENC28J60 Configuration Settings: * * CONFIG_NET_ENC28J60 - Enabled ENC28J60 support - * CONFIG_ENC28J60_OWNBUS - Set if the ENC28J60 is the only active device on - * the SPI bus. No locking or SPI configuration will be performed. All - * transfers will be performed from the ENC2J60 interrupt handler. * CONFIG_ENC28J60_SPIMODE - Controls the SPI mode * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 @@ -110,7 +107,7 @@ /* We need to have the work queue to handle SPI interrupts */ -#if !defined(CONFIG_SCHED_WORKQUEUE) && !defined(CONFIG_ENC28J60_OWNBUS) +#if !defined(CONFIG_SCHED_WORKQUEUE) && !defined(CONFIG_SPI_OWNBUS) # error "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)" #endif @@ -189,7 +186,7 @@ struct enc_driver_s * interrupt handler. */ -#ifndef CONFIG_ENC28J60_OWNBUS +#ifndef CONFIG_SPI_OWNBUS struct work_s work; /* Work queue support */ #endif @@ -221,7 +218,7 @@ static struct enc_driver_s g_enc28j60[CONFIG_ENC28J60_NINTERFACES]; /* Low-level SPI helpers */ static inline void enc_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_ENC28J60_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void enc_select(FAR struct spi_dev_s *spi); static inline void enc_deselect(FAR struct spi_dev_s *spi); #else @@ -315,7 +312,7 @@ static inline void enc_configspi(FAR struct spi_dev_s *spi) * Otherwise, don't bother because it might change. */ -#ifdef CONFIG_ENC28J60_OWNBUS +#ifdef CONFIG_SPI_OWNBUS SPI_SETMODE(spi, CONFIG_ENC28J60_SPIMODE); SPI_SETBITS(spi, 8); #ifdef CONFIG_ENC28J60_FREQUENCY @@ -340,7 +337,7 @@ static inline void enc_configspi(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifdef CONFIG_ENC28J60_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void enc_select(FAR struct spi_dev_s *spi) { /* We own the SPI bus, so just select the chip */ @@ -385,7 +382,7 @@ static void enc_select(FAR struct spi_dev_s *spi) * ****************************************************************************/ -#ifdef CONFIG_ENC28J60_OWNBUS +#ifdef CONFIG_SPI_OWNBUS static inline void enc_deselect(FAR struct spi_dev_s *spi) { /* We own the SPI bus, so just de-select the chip */ @@ -1492,7 +1489,7 @@ static int enc_interrupt(int irq, FAR void *context) DEBUGASSERT(priv->irq == irq); -#ifdef CONFIG_ENC28J60_OWNBUS +#ifdef CONFIG_SPI_OWNBUS /* In very simple environments, we own the SPI and can do data transfers * from the interrupt handler. That is actually a very bad idea in any * case because it keeps interrupts disabled for a long time. diff --git a/nuttx/examples/nx/nx_kbdin.c b/nuttx/examples/nx/nx_kbdin.c index 5b08cabbe..3088885ba 100644 --- a/nuttx/examples/nx/nx_kbdin.c +++ b/nuttx/examples/nx/nx_kbdin.c @@ -63,10 +63,20 @@ * pixel depths that are not directly addressable (1,2,4, and 24). */ -#if CONFIG_EXAMPLES_NX_BPP == 8 +#if CONFIG_EXAMPLES_NX_BPP == 1 +# define RENDERER nxf_convert_1bpp +#elif CONFIG_EXAMPLES_NX_BPP == 2 +# define RENDERER nxf_convert_2bpp +#elif CONFIG_EXAMPLES_NX_BPP == 2 +# define RENDERER nxf_convert_4bpp +#elif CONFIG_EXAMPLES_NX_BPP == 4 +# define RENDERER nxf_convert_8bpp +#elif CONFIG_EXAMPLES_NX_BPP == 8 # define RENDERER nxf_convert_8bpp #elif CONFIG_EXAMPLES_NX_BPP == 16 # define RENDERER nxf_convert_16bpp +#elif CONFIG_EXAMPLES_NX_BPP == 24 +# define RENDERER nxf_convert_24bpp #elif CONFIG_EXAMPLES_NX_BPP == 32 # define RENDERER nxf_convert_32bpp #else diff --git a/nuttx/include/nuttx/enc28j60.h b/nuttx/include/nuttx/enc28j60.h index efa4ed652..f668b6cc6 100755 --- a/nuttx/include/nuttx/enc28j60.h +++ b/nuttx/include/nuttx/enc28j60.h @@ -50,9 +50,6 @@ /* ENC28J60 Configuration Settings: * * CONFIG_NET_ENC28J60 - Enabled ENC28J60 support - * CONFIG_ENC28J60_OWNBUS - Set if the ENC28J60 is the only active device on - * the SPI bus. No locking or SPI configuration will be performed. All - * transfers will be performed from the ENC2J60 interrupt handler. * CONFIG_ENC28J60_SPIMODE - Controls the SPI mode * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 diff --git a/nuttx/include/nuttx/p14201.h b/nuttx/include/nuttx/p14201.h index 9dfbf8b00..443d2537a 100755 --- a/nuttx/include/nuttx/p14201.h +++ b/nuttx/include/nuttx/p14201.h @@ -1,5 +1,6 @@ /**************************************************************************** * include/nuttx/p14201.h + * Application interface to the RiT P14201 OLED driver * * Copyright (C) 2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -49,13 +50,17 @@ /* P14201 Configuration Settings: * * CONFIG_LCD_P14201 - Enable P14201 support - * CONFIG_P14201_OWNBUS - Set if the P14201 is the only active device on the SPI bus. - * No locking or SPI configuration will be performed. All transfers will be performed - * from the ENC2J60 interrupt handler. * CONFIG_P14201_SPIMODE - Controls the SPI mode * CONFIG_P14201_FREQUENCY - Define to use a different bus frequency * CONFIG_P14201_NINTERFACES - Specifies the number of physical P14201 devices that * will be supported. + * CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory + * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 96 / 2 = 6Kb. If this + * is defined, then the driver will be fully functioned. If not, then it will have the + * following limitations: + * + * - Reading graphics memory cannot be supported, and + * - All pixel writes must be aligned to byte boundaries. * * Required LCD driver settings: * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. diff --git a/nuttx/include/nuttx/spi.h b/nuttx/include/nuttx/spi.h index ce97c5183..12d9b0aee 100644 --- a/nuttx/include/nuttx/spi.h +++ b/nuttx/include/nuttx/spi.h @@ -50,7 +50,16 @@ * Pre-processor Definitions ****************************************************************************/ -/* Access macros */ +/* Configuration ************************************************************/ + +/* CONFIG_SPI_OWNBUS - Set if there is only one active device on the SPI bus. + * No locking or SPI configuration will be performed. It is not necessary + * for clients to lock, re-configure, etc.. + * CONFIG_SPI_EXCHANGE - Driver supports a single exchange method + * (vs a recvblock() and sndblock ()methods). + */ + +/* Access macros ************************************************************/ /**************************************************************************** * Name: SPI_LOCK @@ -73,7 +82,11 @@ * ****************************************************************************/ -#define SPI_LOCK(d,l) ((d)->ops->lock ? (d)->ops->lock(d,l) : OK) +#ifndef CONFIG_SPI_OWNBUS +# define SPI_LOCK(d,l) (d)->ops->lock(d,l) +#else +# define SPI_LOCK(d,l) +#endif /**************************************************************************** * Name: SPI_SELECT @@ -326,7 +339,9 @@ enum spi_mode_e struct spi_dev_s; struct spi_ops_s { +#ifndef CONFIG_SPI_OWNBUS int (*lock)(FAR struct spi_dev_s *dev, bool lock); +#endif void (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected); uint32_t (*setfrequency)(FAR struct spi_dev_s *dev, uint32_t frequency); -- cgit v1.2.3