sipo.c
Go to the documentation of this file.
00001
00043 #include "sipo.h"
00044
00045 #include "hw/hw_sipo.h"
00046 #include "cfg/cfg_sipo.h"
00047
00048 #define LOG_LEVEL  SIPO_LOG_LEVEL
00049 #define LOG_FORMAT SIPO_LOG_FORMAT
00050 #include <cfg/log.h>
00051 #include <cfg/compiler.h>
00052
00053 #include <io/kfile.h>
00054
00055 #include <string.h>
00056
00057
00058 #define SIPO_DATAORDER_START(order)          (order ? SIPO_DATAORDER_START_LSB : SIPO_DATAORDER_START_MSB)
00059 #define SIPO_DATAORDER_SHIFT(shift, order)   (order ?  ((shift) <<= 1) : ((shift) >>= 1))
00060 
00064 INLINE void sipo_putchar(uint8_t c, uint8_t bit_order, uint8_t clock_pol)
00065 {
00066     uint8_t shift = SIPO_DATAORDER_START(bit_order);
00067
00068     for(int i = 0; i < 8; i++)
00069     {
00070         if((c & shift) == 0)
00071             SIPO_SI_LOW();
00072         else
00073             SIPO_SI_HIGH();
00074
00075         SIPO_SI_CLOCK(clock_pol);
00076
00077         SIPO_DATAORDER_SHIFT(shift, bit_order);
00078     }
00079 }
00080
00081
00082 #if !CONFIG_SIPO_DISABLE_OLD_API
00083 
00086 static size_t sipo_write(struct KFile *_fd, const void *_buf, size_t size)
00087 {
00088     const uint8_t *buf = (const uint8_t *)_buf;
00089     Sipo *fd = SIPO_CAST(_fd);
00090     size_t write_len = size;
00091
00092     ASSERT(buf);
00093
00094     SIPO_SET_SI_LEVEL();
00095     SIPO_SET_CLK_LEVEL(fd->clock_pol);
00096     SIPO_SET_LD_LEVEL(fd->load_device, fd->load_pol);
00097
00098     // Load into the shift register all the buffer bytes
00099     while(size--)
00100         sipo_putchar(*buf++, fd->bit_order, fd->clock_pol);
00101
00102     // We finsh to load bytes, so load it.
00103     SIPO_LOAD(fd->load_device, fd->load_pol);
00104
00105     // Enable the sipo output
00106     SIPO_ENABLE();
00107
00108     return write_len;
00109 }
00110
00111 #else /* New api */
00112
00116 static size_t sipo_write(struct KFile *_fd, const void *_buf, size_t size)
00117 {
00118     const uint8_t *buf = (const uint8_t *)_buf;
00119     Sipo *fd = SIPO_CAST(_fd);
00120     size_t write_len = size;
00121
00122     ASSERT(buf);
00123
00124     SIPO_SET_SI_LEVEL();
00125     SIPO_SET_CLK_LEVEL(fd->settings & SIPO_CLOCK_POL);
00126     SIPO_SET_LD_LEVEL(fd->device, fd->settings & SIPO_LOAD_LEV);
00127
00128     // Load into the shift register all the buffer bytes
00129     while(size--)
00130         sipo_putchar(*buf++, fd->settings & SIPO_DATAORDER,
00131             fd->settings & SIPO_CLOCK_POL);
00132
00133     // We finsh to load bytes, so load it.
00134     SIPO_LOAD(fd->device, fd->settings & SIPO_LOAD_LEV);
00135
00136     // Enable the sipo output
00137     SIPO_ENABLE();
00138
00139     return write_len;
00140 }
00141 #endif
00142 
00143
00144 INLINE void init(Sipo *fd)
00145 {
00146     ASSERT(fd);
00147
00148     //Set kfile struct type as a generic kfile structure.
00149     DB(fd->fd._type = KFT_SIPO);
00150
00151     // Set up SIPO writing functions.
00152     fd->fd.write = sipo_write;
00153
00154     // Init all pins to manage the shift register
00155     SIPO_INIT_PIN();
00156 }
00157
00158
00159 #if !CONFIG_SIPO_DISABLE_OLD_API
00160 
00166 DEPRECATED void sipo_init_1(Sipo *fd)
00167 {
00168     init(fd);
00169 }
00170 #else /* New api */
00171
00180 void sipo_init_3(Sipo *fd, SipoMap dev, uint8_t settings)
00181 {
00182     memset(fd, 0, sizeof(fd));
00183     fd->settings = settings;
00184     fd->device = dev;
00185     init(fd);
00186 }
00187 #endif