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