sipo.c
Go to the documentation of this file.00001
00043 #include "sipo.h"
00044
00045 #include "hw/hw_sipo.h"
00046
00047 #include <cfg/compiler.h>
00048 #include <cfg/log.h>
00049
00050 #include <kern/kfile.h>
00051
00052 #include <string.h>
00053
00054
00055 #define SIPO_DATAORDER_START(order) (order ? SIPO_DATAORDER_START_LSB : SIPO_DATAORDER_START_MSB)
00056 #define SIPO_DATAORDER_SHIFT(shift, order) (order ? ((shift) <<= 1) : ((shift) >>= 1))
00057
00061 INLINE void sipo_putchar(uint8_t c, uint8_t bit_order, uint8_t clock_pol)
00062 {
00063 uint8_t shift = SIPO_DATAORDER_START(bit_order);
00064
00065 for(int i = 0; i < 8; i++)
00066 {
00067 if((c & shift) == 0)
00068 SIPO_SI_LOW();
00069 else
00070 SIPO_SI_HIGH();
00071
00072 SIPO_SI_CLOCK(clock_pol);
00073
00074 SIPO_DATAORDER_SHIFT(shift, bit_order);
00075 }
00076 }
00077
00081 static size_t sipo_write(struct KFile *_fd, const void *_buf, size_t size)
00082 {
00083 const uint8_t *buf = (const uint8_t *)_buf;
00084 Sipo *fd = SIPO_CAST(_fd);
00085 size_t write_len = size;
00086
00087 ASSERT(buf);
00088
00089 SIPO_SET_SI_LEVEL();
00090 SIPO_SET_CLK_LEVEL(fd->clock_pol);
00091 SIPO_SET_LD_LEVEL(fd->load_device, fd->load_pol);
00092
00093
00094 while(size--)
00095 sipo_putchar(*buf++, fd->bit_order, fd->clock_pol);
00096
00097
00098 SIPO_LOAD(fd->load_device, fd->load_pol);
00099
00100 return write_len;
00101 }
00102
00106 void sipo_init(Sipo *fd)
00107 {
00108 ASSERT(fd);
00109
00110 memset(fd, 0, sizeof(Sipo));
00111
00112
00113 DB(fd->fd._type = KFT_SIPO);
00114
00115
00116 fd->fd.write = sipo_write;
00117
00118 SIPO_INIT_PIN();
00119
00120
00121 SIPO_ENABLE();
00122 }