1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
4 * 2019/7/25 - ROBIN KRENS
8 * Basic driver for the TM1637. The TM1637 is 8 segment
9 * ledclock peripheral. Communication is similar to I2C,
10 * but not completely. There is no address selecting.
12 * Alternative I2C protocol : (W)rite or (R)ead
13 * | Start | ADDRESS | W | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
14 * | Start | ADDRESS | R | ACK/NACK | DATA | ACK/NACK | (d+a*n) | St
23 #include <sys/robsys.h>
25 #include <lib/regfunc.h>
26 #include <lib/string.h>
27 #include <lib/stdio.h>
29 #include <drivers/tm1637.h>
37 #define DISPLAY_ON 0x8F
38 #define DISPLAY_OFF 0x11
40 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their
41 GPIOs must be configured as open-drain. So, you have to add two additional resistors to
42 pull-up I2C lines. Something between 4K and 10K is a proven value.
49 /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings
50 Configure the clock control registers CCR
51 Configure the rise time register TRIS
52 Program the I2C_CR1 register to enable the peripheral
54 ENABLE GPIOB6 and B7*/
56 regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT);
57 regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT);
58 // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ?
60 regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE);
62 regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz
63 regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1)
64 regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard mode, output 100 kHz (100hz* / perip)
66 regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable
70 static void start_condition() {
72 regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
76 static void stop_condition() {
78 regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
81 static int buf_empty() {
83 while(!(*I2C_SR1 & 0x80)) {
95 while(!(*I2C_SR1 & 0x2)) {
100 uint32_t a = *I2C_SR2;
108 while(!(*I2C_SR1 & 0x8)) {
113 //uint32_t a = *I2C_SR2;
121 for (int i = 0; i < TIMEOUT; i++)
125 void set_brightness(uint8_t degree) {
129 // regw_u32(I2C_DR, 0xF0, 0, OWRITE);
131 // cputs("Error: can not set dummy header");
133 regw_u32(I2C_DR, 0xF1, 0, OWRITE);
141 void tm1637_start() {
143 // regw_u32(I2C_CR1, 0x1, 8, SETBIT);
144 // uint32_t read_status = *I2C_SR1;
146 // regw_u32(I2C_DR, DATASET, 0, OWRITE);
148 // read_status = *I2C_SR1;
149 // read_status = *I2C_SR2;
153 // start_condition();
154 // //uint32_t statusr = *I2C_SR1; // clear start_signal
155 // regw_u32(I2C_DR, 0x20, 0, OWRITE); // write to address CMD
157 // cputs("TIMEOUT!");
158 // //statusr = *I2C_SR1;
159 // //statusr = *I2C_SR2;
165 regw_u32(I2C_DR, 0x20, 0, OWRITE); // dummy address
167 cputs("Error: initiating write command\n");
174 regw_u32(I2C_DR, 0xF0, 0, OWRITE); // dummy header F0 ignored! any value will do as long as last bit is not set
176 cputs("Error: dummy addr-10 header not acknowledged\n");
177 regw_u32(I2C_DR, 0x04, 0, OWRITE);
179 cputs("Error: can't set location\n");
180 regw_u32(I2C_DR, 0x04, 0, OWRITE);
182 cputs("Error: can't write\n");
183 regw_u32(I2C_DR, 0x08, 0, OWRITE);
185 cputs("Error: can't write\n");
186 regw_u32(I2C_DR, 0x08, 0, OWRITE);
188 cputs("Error: can't write\n");
192 regw_u32(I2C_DR, 0x00, 0, OWRITE); // ? dummy address
195 regw_u32(I2C_DR, 0x03, 0, OWRITE);
198 regw_u32(I2C_DR, 0xFF, 0, OWRITE);
200 cputs("TIMEOUT2B"); */
205 set_brightness(0x00);
212 regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
218 /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
219 uint32_t read_status = *I2C_SR1;
220 regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD
221 read_status = *I2C_SR1;
222 read_status = *I2C_SR2;
223 regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
224 read_status = *I2C_SR1;
226 regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
227 read_status = *I2C_SR1;
228 regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address
229 read_status = *I2C_SR1;
230 read_status = *I2C_SR2;
231 regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six
233 regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop
234 read_status = *I2C_SR1;
236 regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start
237 read_status = *I2C_SR1;
239 regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE);
240 read_status = *I2C_SR1;
241 regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */
247 //regw_u32(I2C_CR1, 0x0, 9, SETBIT);