From 18beee58326ca26ce9be3382bae7ef117878b003 Mon Sep 17 00:00:00 2001 From: Robin Krens Date: Tue, 13 Aug 2019 20:30:42 +0800 Subject: [PATCH] set address location, reset I2C --- drivers/tm1637.c | 141 ++++++++++++++++++++++++++++++++++++++++++----------- include/sys/mmap.h | 1 + 2 files changed, 113 insertions(+), 29 deletions(-) diff --git a/drivers/tm1637.c b/drivers/tm1637.c index 7650ee3..26b4c2e 100644 --- a/drivers/tm1637.c +++ b/drivers/tm1637.c @@ -30,13 +30,23 @@ #define TIMEOUT 1000 -#define DATASET 0x40 -#define CONTROL 0x80 -#define SETADDR 0xC0 - #define DISPLAY_ON 0x8F #define DISPLAY_OFF 0x11 + +/* +0 = 0x00 +1 = 0x60 +2 = 0xDA +3 = 0xF2 +4 = 0x66 +5 = 0xB6 +6 = 0xBE +7 = 0xE0 +8 = 0xFF +9 = 0xF6 +*/ + /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their GPIOs must be configured as open-drain. So, you have to add two additional resistors to pull-up I2C lines. Something between 4K and 10K is a proven value. @@ -67,6 +77,26 @@ void tm1637_init() { } +void tm1637_reset() { + + regw_u32(RCC_APB1RSTR, 0x1, 21, SETBIT); + + regw_u32(RCC_APB1RSTR, 0x00000000, 0, OWRITE); // clr + //regw_u32(RCC_APB2ENR, 0x1, 3, SETBIT); + // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ? + + regw_u32(RCC_APB1ENR, 0x1, 21, SETBIT); + //regw_u32(GPIOB_CRL, 0xEE444444, 0, OWRITE); + + regw_u32(I2C_CR2, 0x2, 0, OWRITE); //2 MHz + regw_u8(I2C_TRISE, 0x3, 0, OWRITE); // MAX = 1000ns, TPCLK1 = 500ns (+1) + regw_u32(I2C_CCR, 0x000A, 0, OWRITE); // standard mode, output 100 kHz (100hz* / perip) + + regw_u32(I2C_CR1, 0x1, 0, OWRITE); // enable + + +} + static void start_condition() { regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start @@ -115,6 +145,17 @@ int ack10_recv() { } +int idle() { + int cnt = 0; + while(*I2C_SR2 & 0x2) { + cnt++; + if (cnt > TIMEOUT) + return 0; + } + + return 1; +} + int delay() { int a = 0; @@ -135,11 +176,38 @@ void set_brightness(uint8_t degree) { cputs("TIMEOUT3!"); stop_condition(); + // reset bus + regw_u32(I2C_CR1, 0x1, 15, SETBIT); + +} + + +void set_startseg(int offset) { + + start_condition(); + regw_u32(I2C_DR, 0x20, 0, OWRITE); + if(!ack_recv()) + cputs("Error: initiating write for start segment \n"); + + stop_condition(); + + if(!idle()) + cputs("Error: timeout"); + + start_condition(); + regw_u32(I2C_DR, 0x03, 0, OWRITE); + if(!ack_recv()) + cputs("Error: Can't set start segment \n"); + + stop_condition(); + regw_u32(I2C_CR1, 0x1, 15, SETBIT); + } void tm1637_start() { +unsigned char display_number[10] = {0x00, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFF, 0xF6}; // regw_u32(I2C_CR1, 0x1, 8, SETBIT); // uint32_t read_status = *I2C_SR1; @@ -160,35 +228,47 @@ void tm1637_start() { // stop_condition(); // // //delay(); - - start_condition(); - regw_u32(I2C_DR, 0x20, 0, OWRITE); // dummy address - if(!ack_recv()) - cputs("Error: initiating write command\n"); - stop_condition(); - - delay(); + set_startseg(0); + + if(!idle()) + cputs("Error: timeout"); + + tm1637_reset(); + +// start_condition(); +// regw_u32(I2C_DR, 0x20, 0, OWRITE); +// if(!ack_recv()) +// cputs("Error: initiating write command\n"); +// +// stop_condition(); +// +// if(!idle()) +// cputs("Error: timeout"); start_condition(); - regw_u32(I2C_DR, 0xF0, 0, OWRITE); // dummy header F0 ignored! any value will do as long as last bit is not set +// regw_u32(I2C_DR, 0xF0, 0, OWRITE); // dummy header F0 ignored! any value will do as long as last bit is not set +// if(!ack10_recv()) +// cputs("Error: dummy addr-10 header not acknowledged\n"); + regw_u32(I2C_DR, display_number[6], 0, OWRITE); // use ack10 if higher if(!ack10_recv()) - cputs("Error: dummy addr-10 header not acknowledged\n"); - regw_u32(I2C_DR, 0x04, 0, OWRITE); - if(!ack_recv()) cputs("Error: can't set location\n"); - regw_u32(I2C_DR, 0x04, 0, OWRITE); - if(!buf_empty()) - cputs("Error: can't write\n"); - regw_u32(I2C_DR, 0x08, 0, OWRITE); - if(!buf_empty()) - cputs("Error: can't write\n"); - regw_u32(I2C_DR, 0x08, 0, OWRITE); - if(!buf_empty()) - cputs("Error: can't write\n"); - stop_condition(); +// regw_u32(I2C_DR, 0xF4, 0, OWRITE); +// if(!buf_empty()) +// cputs("Error: can't write\n"); +// regw_u32(I2C_DR, 0x08, 0, OWRITE); +// if(!buf_empty()) +// cputs("Error: can't write\n"); +// regw_u32(I2C_DR, 0x08, 0, OWRITE); +// if(!buf_empty()) +// cputs("Error: can't write\n"); + stop_condition(); + + - /* + + regw_u32(I2C_CR1, 0x1, 15, SETBIT); + /* regw_u32(I2C_DR, 0x00, 0, OWRITE); // ? dummy address if(!ack_recv()) cputs("TIMEOUTA"); @@ -199,9 +279,12 @@ void tm1637_start() { if(!buf_empty()) cputs("TIMEOUT2B"); */ // -// + if(!idle()) + cputs("Error: timeout"); + + + tm1637_reset(); - delay(); set_brightness(0x00); diff --git a/include/sys/mmap.h b/include/sys/mmap.h index 4fd043d..a5d2228 100644 --- a/include/sys/mmap.h +++ b/include/sys/mmap.h @@ -54,6 +54,7 @@ /* SYSTEM CONTROL REGISTER */ #define SYSCTRL_RCC MEM_ADDR(0x40021000) #define RCC_APB1ENR MEM_ADDR(0x4002101C) // register to enable I2C +#define RCC_APB1RSTR MEM_ADDR(0x40021010) // register to reset I2C #define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1 #define SYSCTRL_RIS MEM_ADDR(0x400FE050) -- 2.7.4