From: Robin Krens Date: Tue, 13 Aug 2019 16:49:37 +0000 (+0800) Subject: Merge branch 'tm1637' X-Git-Url: https://robinkrens.nl/gitweb/?p=cortex-from-scratch;a=commitdiff_plain;h=8b8d6edcd57f69b40f430bc172e1c290a629a6a9;hp=-c Merge branch 'tm1637' --- 8b8d6edcd57f69b40f430bc172e1c290a629a6a9 diff --combined drivers/tm1637.c index a2889fd,485d81d..8c8ce5b --- a/drivers/tm1637.c +++ b/drivers/tm1637.c @@@ -28,20 -28,32 +28,32 @@@ #include -#define TIMEOUT 1000 +#define TIMEOUT 5000 - #define DATASET 0x40 - #define CONTROL 0x80 - #define SETADDR 0xC0 - - #define DISPLAY_ON 0x8F - #define DISPLAY_OFF 0x11 + #define DOT true + #define NODOT false + + + /* + 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. */ + /* BIG ENDIAN! */ + void tm1637_init() { /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings @@@ -65,6 -77,26 +77,26 @@@ } + 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 @@@ -76,22 -108,45 +108,45 @@@ static void stop_condition() regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop } - int ack_recv() { + static int buf_empty() { + int cnt = 0; + while(!(*I2C_SR1 & 0x80)) { + cnt++; + if (cnt > TIMEOUT) { + return 0; + } + } + return 1; + } + /* Wait for an acknowledge from the peripheral */ + int ack_recv() { int cnt = 0; while(!(*I2C_SR1 & 0x2)) { cnt++; if (cnt > TIMEOUT) return 0; } + uint32_t a = *I2C_SR2; // need to read SR2 register! + return 1; + } + + /* Similar, but SR2 register is not read */ + int ack10_recv() { + int cnt = 0; + while(!(*I2C_SR1 & 0x8)) { + cnt++; + if (cnt > TIMEOUT) + return 0; + } return 1; } - int buf_empty() { + int idle() { int cnt = 0; - while(!(*I2C_SR1 & 0x80)) { + while(*I2C_SR2 & 0x2) { cnt++; if (cnt > TIMEOUT) return 0; @@@ -107,82 -162,86 +162,85 @@@ int delay() a++; } - void tm1637_start() { + void set_display(bool on, uint8_t degree) { + + start_condition(); + + regw_u32(I2C_DR, 0xF1, 0, OWRITE); + if(!ack_recv()) + cputs("Can't switch on display!"); + stop_condition(); + + // reset bus + regw_u32(I2C_CR1, 0x1, 15, SETBIT); - // regw_u32(I2C_CR1, 0x1, 8, SETBIT); - // uint32_t read_status = *I2C_SR1; + } + + + void set_segment(int offset, char value, bool dot) { + + int (*ack)() = ack_recv; /* Scary function pointer :D */ - // regw_u32(I2C_DR, DATASET, 0, OWRITE); - // conform DATA - // read_status = *I2C_SR1; - // read_status = *I2C_SR2; - uint32_t statusr; + if (offset > 3) { + cputs("Offset incorrect"); + } + + if (dot) { + value = value | 0x1; + } + int start_pos_cmd = 0x03 | (offset & 0x01) << 7 | (offset & 0x2) << 5 ; start_condition(); - //uint32_t statusr = *I2C_SR1; // clear start_signal - regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD + regw_u32(I2C_DR, 0x20, 0, OWRITE); if(!ack_recv()) - cputs("TIMEOUT!"); - //statusr = *I2C_SR1; - //statusr = *I2C_SR2; + cputs("Error: initiating write for start segment \n"); + stop_condition(); + + if(!idle()) + cputs("Error: timeout"); - //delay(); start_condition(); - //statusr = *I2C_SR1; // clear start_signal - regw_u32(I2C_DR, 0xC1, 0, OWRITE); - if(!ack_recv()) - cputs("TIMEOUT2!"); - //statusr = *I2C_SR1; - //statusr = *I2C_SR2; - regw_u32(I2C_DR, 0x7D, 0, OWRITE); - if(!buf_empty()) - cputs("TIMEOUT3!"); + regw_u32(I2C_DR, start_pos_cmd, 0, OWRITE); + if(!ack()) + cputs("Error: Can't set start segment \n"); + stop_condition(); + regw_u32(I2C_CR1, 0x1, 15, SETBIT); + + tm1637_reset(); - /* delay(); + // if (value & 0xF0) + // ack = &ack10_recv; start_condition(); - statusr = *I2C_SR1; - regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE); + regw_u32(I2C_DR, value, 0, OWRITE); // use ack10 if higher if(!ack_recv()) - cputs("TIMEOUT4!"); - stop_condition(); */ + cputs("Error: can't set location\n"); + stop_condition(); - + regw_u32(I2C_CR1, 0x1, 15, SETBIT); - /* regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start - uint32_t read_status = *I2C_SR1; - regw_u32(I2C_DR, 0x40, 0, OWRITE); // write to address CMD - read_status = *I2C_SR1; - read_status = *I2C_SR2; - regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop - read_status = *I2C_SR1; + tm1637_reset(); + } - regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start - read_status = *I2C_SR1; - regw_u32(I2C_DR, 0xC1, 0, OWRITE); // segment address - read_status = *I2C_SR1; - read_status = *I2C_SR2; - regw_u32(I2C_DR, 0x7D, 0, OWRITE); // write a six - regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop - read_status = *I2C_SR1; - regw_u32(I2C_CR1, 0x1, 8, SETBIT); //start - read_status = *I2C_SR1; + void tm1637_start() { - regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE); - read_status = *I2C_SR1; - regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */ + unsigned char display_number[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6}; - } - void tm1637_stop() { + char love[4] = { 0x1C, 0xFC, 0x7C, 0x9E }; + + for (int i = 0; i < 4; i++) { + set_segment(i, love[i], NODOT); + } - //regw_u32(I2C_CR1, 0x0, 9, SETBIT); - } + set_display(true, 0); + } diff --combined include/sys/mmap.h index db6cf5c,a5d2228..9aae914 --- a/include/sys/mmap.h +++ b/include/sys/mmap.h @@@ -32,10 -32,7 +32,10 @@@ /* SYSTEM INFO AND DEBUG */ #define MCU_ID MEM_ADDR(0xE000ED00) -#define FLASH_MEM MEM_ADDR(0x1FFFF000) +#define FLASH_MEM MEM_ADDR(0x1FFFF000) + +/* POWER CONTROL REGISTERS */ +#define PWR_CR MEM_ADDR(0x40007000) /* SYSTEM CONTROL BLOCK REGISTER */ #define SCB_VTOR MEM_ADDR(0xE000ED08) // VECTOR TABLE @@@ -49,16 -46,15 +49,17 @@@ /* SYSTICK REGISTER */ #define STK_CTRL MEM_ADDR(0xE000E010) #define STK_RELOAD MEM_ADDR(0xE000E014) +#define STK_CALIB MEM_ADDR(0xE000E01C) -/* CLOCK REGISTER */ +/* RESET AND CLOCK REGISTER */ #define RCC_CR MEM_ADDR(0x40021000) #define RCC_CFGR MEM_ADDR(0x40021004) +#define RCC_BDCR MEM_ADDR(0x40021020) /* 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) @@@ -67,15 -63,9 +68,15 @@@ #define GPIOPA_AFSEL MEM_ADDR(0x40004420) #define GPIOA_CRH MEM_ADDR(0x40010804) // for USART1 +#define GPIOA_ODR MEM_ADDR(0x4001080C) #define GPIOB_CRL MEM_ADDR(0x40010C00) // low register (!) for I2C1 -#define GPIOC_CRL MEM_ADDR(0x40011000) // for led -#define GPIOC_ODR MEM_ADDR(0x4001100C) // +#define GPIOB_BSRR MEM_ADDR(0x40010C10) +#define GPIOC_CRL MEM_ADDR(0x40011000) // led +#define GPIOC_CRH MEM_ADDR(0x40011004) +#define GPIOC_ODR MEM_ADDR(0x4001100C) + +#define GPIOD_CRL MEM_ADDR(0x40011400) +#define GPIOD_ODR MEM_ADDR(0x4001140C) #define AFIO_EVCR MEM_ADDR(0x40010000) @@@ -100,26 -90,3 +101,26 @@@ #define USART1_CR1 MEM_ADDR(0x4001380C) #define USART1_CR2 MEM_ADDR(0x40013810) #define USART1_CR3 MEM_ADDR(0x40013814) + +/* REAL TIME CLOCK REGISTERS */ +#define RTC_CRH MEM_ADDR(0x40002800) // interrupts +#define RTC_CRL MEM_ADDR(0x40002804) +#define RTC_PRLL MEM_ADDR(0x4000280C) +#define RTC_CNTH MEM_ADDR(0x40002818) +#define RTC_CNTL MEM_ADDR(0x4000281C) +/* BACKUP (CALIBR) REGISTERS */ +#define BKP_RTCCR MEM_ADDR(0x40006C2C) // RTC Calibration + +#define TIM4_CR1 MEM_ADDR(0x40000800) +#define TIM4_RCR MEM_ADDR(0x40000830) +#define TIM4_ARR MEM_ADDR(0x4000082C) +#define TIM4_EGR MEM_ADDR(0x40000814) +#define TIM4_SR1 MEM_ADDR(0x40000810) +#define TIM4_CCR1 MEM_ADDR(0x40000834) +#define TIM4_CCR2 MEM_ADDR(0x40000838) +#define TIM4_PSC MEM_ADDR(0x40000828) +#define TIM4_SMCR MEM_ADDR(0x40000808) +#define TIM4_CCER MEM_ADDR(0x40000820) +//#define TIM1_BDTR MEM_ADDR(0x40000844) +#define TIM4_CCMR1 MEM_ADDR(0x40000818) +#define TIM4_DIER MEM_ADDR(0x4000080C) diff --combined include/sys/robsys.h index 78aedef,e02eded..9a19a47 --- a/include/sys/robsys.h +++ b/include/sys/robsys.h @@@ -1,23 -1,8 +1,23 @@@ #ifndef __SYSTEM_H #define __SYSTEM_H -/* CLOCK.C */ + +/* CLOCK.C + * Board specific clock settings. These boards often come with two + * external oscillators: one high speed (8MHz) and one low speed (~30kHz). + * These values are used throughout the code to calculator desired baud + * rates etc. + */ - #define ENABLE_HSE ++//#define ENABLE_HSE +//efine CRYSTAL_MHZ 8 +//efine CLKSPEED_MHZ 72 extern void clock_init(); +// extern int clock_test(); +// extern void clock_reset(); + +/* RTC.C */ +#define ENABLE_RTC +extern void rtc_init(); /* IVT.C */ extern void ivt_init(); @@@ -29,6 -14,12 +29,6 @@@ extern void systick_init() /* SYSINFO.C */ extern void sysinfo(); -/* MM.C DELETE TODO */ -//extern void mm_init(); -//extern void * malloc(size_t); -//extern void free(void *); -//extern void test_memory(uint32_t *); - /* POOL.c */ extern void pool_init(size_t, unsigned int, uint32_t *); extern void * alloc(); diff --combined main.c index 51c2b10,342059e..8455b46 --- a/main.c +++ b/main.c @@@ -19,60 -19,22 +19,60 @@@ #include #include +#include #include #include #include +#include +#include + +//void sleep() { +// +// __asm__ __volatile__("wfe"); +// +//} void main() { + clock_init(); ivt_init(); uart_init(); // cputs("ROBSYS LOADING...\n"); - systick_init(); - led_init(); + //systick_init(); +// tsensor_output(0xFFFF, 0x7FFF); + + init_printf(NULL, putc); + // SPEED_TEST +/* cputs("START TEST (8MHz) \n"); + int a; + for (int i = 0; i < 20000000; i++) { + a + 2; + } + a = 0; + cputs("END TEST\n"); + + //! + clock_init(); + + cputs("START TEST (??MHz) \n"); + for (int i = 0; i < 20000000; i++) { + a + 2; + } + cputs("END TEST\n"); */ sysinfo(); + +// tsensor_input(5000); +// run(); + + led_init(); - eeprom_at24c_init(); - eeprom_test(); ++// eeprom_at24c_init(); ++// eeprom_test(); +// rtc_init(); + - // tm1637_init(); - // tm1637_start(); + tm1637_init(); + tm1637_start(); //uint32_t test = hextoreg("12345678");