*
* \brief SIPO Module
*
- * The SIPO module transforms a serial input in
- * a parallel output. Please check hw_sipo.h
+ * 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>
#include "hw/hw_sipo.h"
#include <cfg/compiler.h>
+#include <cfg/log.h>
#include <kern/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);
}
}
/**
* 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);
+ 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 have just finished to shift the bytes into the register, now load them.
- SIPO_LOAD();
+ // We finsh to load bytes, so load it.
+ SIPO_LOAD(fd->load_device, fd->load_pol);
return write_len;
}
memset(fd, 0, sizeof(Sipo));
- //Set kfile struct type as a Sipo structure.
+ //Set kfile struct type as a generic kfile structure.
DB(fd->fd._type = KFT_SIPO);
// Set up SIPO writing functions.
SIPO_INIT_PIN();
+ /* Enable sipo output */
+ SIPO_ENABLE();
}
* -->
*
* \brief Generic Serial-in, Parallel-out implementation (SIPO).
- *
- * This module use kfile interface.
*
*
* \version $Id$
*
* \author Andrea Grandi <andrea@develer.com>
* \author Daniele Basile <asterix@develer.com>
- *
+ *
* $WIZ$ module_name = "sipo"
* $WIZ$ module_depends = "kfile"
* $WIZ$ module_hw = "bertos/hw/hw_sipo.h"
- *
*/
+
+
+
+
#ifndef DRV_SIPO_H
#define DRV_SIPO_H
+#include "hw/hw_sipo.h"
+
#include <kern/kfile.h>
+#define SIPO_DATAORDER_START_LSB 1
+#define SIPO_DATAORDER_START_MSB 0x80
+
+/**
+ * Define enum to set sipo data order.
+ */
+typedef enum SipoBitOrder
+{
+ SIPO_DATAORDER_MSB = 0,
+ SIPO_DATAORDER_LSB = 1
+} SipoBitOrder;
+
+/**
+ * Define enum to set the start level of clock.
+ */
+typedef enum SipoClockPol
+{
+ SIPO_START_LOW = 0,
+ SIPO_START_HIGH = 1
+
+} SipoClkPol;
+
+/**
+ * Define enum to set load signal level.
+ */
+typedef enum SipoLoadPol
+{
+ SIPO_LOW_TO_HIGH = 0,
+ SIPO_HIGH_TO_LOW = 1
+
+} SipoLoadPol;
+
/**
* Sipo KFile context structure.
*/
typedef struct Sipo
{
- KFile fd; ///< File descriptor.
+ KFile fd; ///< File descriptor.
+ SipoMap load_device; ///< Descriptor of the device that we want drive.
+ SipoLoadPol load_pol; ///< Set polarity of load signal.
+ SipoClkPol clock_pol; ///< Set polarity of data clock.
+ SipoBitOrder bit_order; ///< Set the order of pushed bits in sipo.
+
} Sipo;
/**