Update sipo api.
[bertos.git] / bertos / drv / sipo.c
index cb821692727b4989a57227b77ae87565a39435f8..046cf72a762ba34a9d5413e01ba663d401be2a9a 100644 (file)
  * invalidate any other reasons why the executable file might be covered by
  * the GNU General Public License.
  *
- * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
  *
  * -->
  *
- * \version $Id$
  *
  * \brief SIPO Module
  *
- * The SIPO module trasform a serial input in
- * a parallel output. Please check hw_sipo.h
- * file to customize hardware relative parameters.
+ * The SIPO module transforms a serial input in a parallel output. Please check hw_sipo.h
+ * file to customize hardware related parameters.
  *
+ * \author Andrea Grandi <andrea@develer.com>
  * \author Daniele Basile <asterix@develer.com>
  */
 
 #include "sipo.h"
 
 #include "hw/hw_sipo.h"
+#include "cfg/cfg_sipo.h"
 
+#define LOG_LEVEL  SIPO_LOG_LEVEL
+#define LOG_FORMAT SIPO_LOG_FORMAT
+#include <cfg/log.h>
 #include <cfg/compiler.h>
 
-#include <kern/kfile.h>
+#include <io/kfile.h>
 
 #include <string.h>
 
+
+#define SIPO_DATAORDER_START(order)          (order ? SIPO_DATAORDER_START_LSB : SIPO_DATAORDER_START_MSB)
+#define SIPO_DATAORDER_SHIFT(shift, order)   (order ?  ((shift) <<= 1) : ((shift) >>= 1))
+
 /**
  * Write a char in sipo shift register
  */
-INLINE void sipo_putchar(uint8_t c)
+INLINE void sipo_putchar(uint8_t c, uint8_t bit_order, uint8_t clock_pol)
 {
+       uint8_t shift = SIPO_DATAORDER_START(bit_order);
+
        for(int i = 0; i < 8; i++)
        {
-               if((c & BV(i)) == 0)
+               if((c & shift) == 0)
                        SIPO_SI_LOW();
                else
                        SIPO_SI_HIGH();
 
-               SIPO_SI_CLOCK();
+               SIPO_SI_CLOCK(clock_pol);
+
+               SIPO_DATAORDER_SHIFT(shift, bit_order);
        }
 }
 
+
+#if !CONFIG_SIPO_DISABLE_OLD_API
 /**
- * Write a buffer into sipo register and when finish to
- * we load it.
+ * Write a buffer into the sipo register and, when finished, give a load pulse.
  */
- static size_t sipo_write(UNUSED_ARG(struct KFile *, fd), const void *_buf, size_t size)
+static size_t sipo_write(struct KFile *_fd, const void *_buf, size_t size)
 {
        const uint8_t *buf = (const uint8_t *)_buf;
+       Sipo *fd = SIPO_CAST(_fd);
        size_t write_len = size;
+
        ASSERT(buf);
 
-       // Load into shift register all byte in buffer
+       SIPO_SET_SI_LEVEL();
+       SIPO_SET_CLK_LEVEL(fd->clock_pol);
+       SIPO_SET_LD_LEVEL(fd->load_device, fd->load_pol);
+
+       // Load into the shift register all the buffer bytes
        while(size--)
-               sipo_putchar(*buf++);
+               sipo_putchar(*buf++, fd->bit_order, fd->clock_pol);
 
-       // We finsh to load bytes into shift register, load it.
-       SIPO_LOAD();
+       // We finsh to load bytes, so load it.
+       SIPO_LOAD(fd->load_device, fd->load_pol);
 
        return write_len;
 }
 
+#else /* New api */
+
 /**
- * Initialize the SIPO
+ * Write a buffer into the sipo register and, when finished, give a load pulse.
  */
-void sipo_init(Sipo *fd)
+static size_t sipo_write(struct KFile *_fd, const void *_buf, size_t size)
 {
-       ASSERT(fd);
+       const uint8_t *buf = (const uint8_t *)_buf;
+       Sipo *fd = SIPO_CAST(_fd);
+       size_t write_len = size;
+
+       ASSERT(buf);
+
+       SIPO_SET_SI_LEVEL();
+       SIPO_SET_CLK_LEVEL(fd->settings & SIPO_CLOCK_POL);
+       SIPO_SET_LD_LEVEL(fd->device, fd->settings & SIPO_LOAD_LEV);
+
+       // Load into the shift register all the buffer bytes
+       while(size--)
+               sipo_putchar(*buf++, fd->settings & SIPO_DATAORDER,
+                       fd->settings & SIPO_CLOCK_POL);
 
-       memset(fd, 0, sizeof(Sipo));
+       // We finsh to load bytes, so load it.
+       SIPO_LOAD(fd->device, fd->settings & SIPO_LOAD_LEV);
+
+       return write_len;
+}
+#endif
+
+
+INLINE void init(Sipo *fd)
+{
+       ASSERT(fd);
 
        //Set kfile struct type as a generic kfile structure.
        DB(fd->fd._type = KFT_SIPO);
 
-       // Set up data flash programming functions.
+       // Set up SIPO writing functions.
        fd->fd.write = sipo_write;
 
        SIPO_INIT_PIN();
 
+       /* Enable sipo output */
+       SIPO_ENABLE();
+}
+
+/**
+ * Initialize the SIPO
+ */
+#if !CONFIG_SIPO_DISABLE_OLD_API
+
+void sipo_init_1(Sipo *fd)
+{
+       init(fd);
+}
+#else /* New api */
+
+void sipo_init_3(Sipo *fd, SipoMap dev, uint8_t settings)
+{
+       memset(fd, 0, sizeof(fd));
+       fd->settings = settings;
+       fd->device = dev;
+       init(fd);
 }
+#endif