From 09e66bc2ce34038a3e47e1ade5413c5464a783cd Mon Sep 17 00:00:00 2001 From: Robin Krens Date: Sat, 10 Aug 2019 00:12:53 +0800 Subject: [PATCH] eeprom at24c signs of life --- Makefile | 2 +- drivers/at24c.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/led.c | 4 +- drivers/tsensor.c | 157 ++++++++++++++++++++++++++------ include/drivers/at24c.h | 7 ++ include/drivers/tsensor.h | 1 + include/sys/mmap.h | 1 + main.c | 8 +- 8 files changed, 370 insertions(+), 34 deletions(-) create mode 100644 drivers/at24c.c create mode 100644 include/drivers/at24c.h diff --git a/Makefile b/Makefile index 65c1294..678ac90 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ _OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o rtc.o OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ)) DDIR = obj/drivers -_DRIVERS = uart.o tm1637.o led.o tsensor.o +_DRIVERS = uart.o tm1637.o led.o tsensor.o at24c.o DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS)) LDIR = obj/lib diff --git a/drivers/at24c.c b/drivers/at24c.c new file mode 100644 index 0000000..25a65fb --- /dev/null +++ b/drivers/at24c.c @@ -0,0 +1,224 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/25 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * + * */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#define TIMEOUT 5000 + +#define READ_CMD 0xA1 +#define WRITE_CMD 0xA0 + + +/* 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. +*/ + +void at24c_init() { + + /* Program the peripheral input clock in I2C_CR2 Register in order to generate correct timings + Configure the clock control registers CCR + Configure the rise time register TRIS + Program the I2C_CR1 register to enable the peripheral + + ENABLE GPIOB6 and B7*/ + + rsetbit(RCC_APB1ENR, 21); + rsetbit(RCC_APB2ENR, 3); + // //regw_u8(AFIO_EVCR, 0x89, 0, SETBIT);// set event control register, output on ? + + rwrite(GPIOB_CRL, 0xEE444444); + + rsetbitsfrom(I2C_CR2, 0, 0x2); // 36 MHz + rwrite(I2C_TRISE, 0x3); // MAX = 1000ns, TPCLK1 = 500ns (+1) + rwrite(I2C_CCR, 0x000A); // standard mode, output 100 kHz (100hz* / perip) + + rsetbit(I2C_CR1, 10); // send ack if receive + + rsetbit(I2C_CR1, 0); // enable + +} + +static void start_condition() { + + rsetbit(I2C_CR1, 8); //start + +} + +static void stop_condition() { + + rsetbit(I2C_CR1, 9); //stop +} + +static int ack_recv() { + + int cnt = 0; + while(!(*I2C_SR1 & 0x2)) { + cnt++; + if (cnt > TIMEOUT) + return 0; + } + + int a = *I2C_SR2; + return 1; + +} + +static int buf_empty() { + int cnt = 0; + while(!(*I2C_SR1 & 0x80)) { + cnt++; + if (cnt > TIMEOUT) + return 0; + } + + return 1; +} + +static void data_recv() { + //int cnt = 0; + while(!(*I2C_SR1 & 0x4)) { + /// cnt++; + // if (cnt > TIMEOUT) + // return 0; + } + //return 1; +} + +static int delay() { + + int a = 0; + for (int i = 0; i < 0xFFFF; i++) + a++; +} + +void at24c_run() { + +// regw_u32(I2C_CR1, 0x1, 8, SETBIT); +// uint32_t read_status = *I2C_SR1; + +// regw_u32(I2C_DR, DATASET, 0, OWRITE); + // conform DATA +// read_status = *I2C_SR1; +// read_status = *I2C_SR2; + + uint32_t statusr; + + start_condition(); + //uint32_t statusr = *I2C_SR1; // clear start_signal + rwrite(I2C_DR, 0xA0); // write to address CMD + if(!ack_recv()) + cputs("CAN'T REACH DEVICE"); + + rwrite(I2C_DR, 0x00); + if(!buf_empty()) + cputs("FAIL"); + rwrite(I2C_DR, 0x00); + if(!buf_empty()) + cputs("FAIL"); + //rwrite(I2C_DR, 0x61); + //if(!buf_empty()) + // cputs("FAIL"); + + //statusr = *I2C_SR1; + //statusr = *I2C_SR2; + stop_condition(); + +// start_condition(); +// rwrite(I2C_DR, 0xA0); // dummy write +// if(!ack_recv()) +// cputs("CAN'T REACH DEVICE"); +// +// rwrite(I2C_DR, 0x00); +// if(!buf_empty()) +// cputs("FAIL"); +// rwrite(I2C_DR, 0x00); +// if(!buf_empty()) +// cputs("FAIL"); +// + delay(); + + start_condition(); // restart condition + rwrite(I2C_DR, 0xA1); // read? to address CMD + if(!ack_recv()) + cputs("COULDN'T START READ CMD"); + + + data_recv(); + //cputs("NO RESPONSE"); + + char a = (char) *I2C_DR; + printf("DATA %c\n", a); + + stop_condition(); + //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!"); + //stop_condition(); + +/* delay(); + + start_condition(); + statusr = *I2C_SR1; + regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE); + if(!ack_recv()) + cputs("TIMEOUT4!"); + stop_condition(); */ + + + /* 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; + + 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; + + regw_u32(I2C_DR, DISPLAY_ON, 0, OWRITE); + read_status = *I2C_SR1; + regw_u32(I2C_CR1, 0x1, 9, SETBIT); //stop */ + +} + + diff --git a/drivers/led.c b/drivers/led.c index 84c4d0a..ca74c14 100644 --- a/drivers/led.c +++ b/drivers/led.c @@ -37,8 +37,8 @@ void led_init() { //rwrite(GPIOD_CRL, 0x44444644); rsetbitsfrom(GPIOD_CRL, 8, 0x6); rsetbitsfrom(GPIOA_CRH, 0, 0x6); - rsetbit(GPIOD_ODR, 2); - rclrbit(GPIOA_ODR, 8); +// rsetbit(GPIOD_ODR, 2); +// rclrbit(GPIOA_ODR, 8); } diff --git a/drivers/tsensor.c b/drivers/tsensor.c index 4f11ec2..3799095 100644 --- a/drivers/tsensor.c +++ b/drivers/tsensor.c @@ -22,30 +22,123 @@ #include -#define PRESCALER 36000 // 1 kHz +#define PRESCALER 36000 // 1 Mhz + +int *ccr1, *ccr2, *ccr1b, *ccr2b; +bool s1, s2; void * update_handler() { + s1 = false; + s2 = false; + ccr1 = 0xFFFFFFFF; + ccr2 = 0xFFFFFFFF; + ccr1b = 0xFFFFFFFF; + ccr2b = 0xFFFFFFFF; + if(rchkbit(TIM4_SR1, 1)) { - - printf("RISING EDGE CAUGHT\n"); - printf("CCR1: %p\n", *TIM4_CCR1); + s1 = true; + // printf("CCR1: %p\n", *TIM4_CCR1); + // printf("CCR2: %p\n", *TIM4_CCR2); + ccr1 = *TIM4_CCR1; + ccr2 = *TIM4_CCR2; + rclrbit(TIM4_SR1, 1); } if(rchkbit(TIM4_SR1, 2)) { - printf("FALLING EDGE CAUGHT\n"); - printf("CCR2: %p\n", *TIM4_CCR2); + s2 = true; + ccr1b = *TIM4_CCR1; + ccr2b = *TIM4_CCR2; + rclrbit(TIM4_SR1, 2); } + if(rchkbit(TIM4_SR1, 6)) { + // printf("TRIGGER\n"); + rclrbit(TIM4_SR1, 6); + } - rclrbit(TIM4_SR1, 1); rclrbit(TIM4_SR1, 0); - rclrbit(TIM4_SR1, 2); // - rclrbit(TIM4_SR1, 9); // OF - rclrbit(TIM4_SR1, 10); // OF - rclrbit(TIM4_SR1, 6); +// rclrbit(TIM4_SR1, 9); // OF +// rclrbit(TIM4_SR1, 10); // OF + // TODO clear overflow tag -} + + printf("SR1/CCR1: %p\n", ccr1); + printf("SR1/CCR2: %p\n", ccr2); + printf("SR2/CCR1: %p\n", ccr1b); + printf("SR2/CCR2: %p\n", ccr2b); + + if (s1) + printf("EDGE DOWN\n"); + if (s2) + printf("EDGE UP\n"); + + s1 = false; + s2 = false; +} + +static void reset() { + rwrite(GPIOB_CRL, 0x44444444); +} + +void * tmp_update_handler() { + + printf("SR: %p\n", *TIM4_SR1); + + rclrbit(TIM4_CR1, 0); /* EMULATOR STOP */ + rclrbit(TIM4_SR1, 0); + rclrbit(TIM4_SR1, 1); + reset(); + tsensor_input(0xFFFF); + +// if(rchkbit(TIM4_SR1, 1)) { +// printf("TEST\n"); +// } + +} + +void * cnt_complete_handler() { + rclrbit(TIM4_CR1, 0); + rclrbit(TIM4_SR1, 0); + rclrbit(TIM4_DIER, 0); + rwrite(GPIOB_CRL, 0x44444444); + printf("CNT COMPLETE\n"); + tsensor_input(0xFFFF); +} + + +void tsensor_simple(uint16_t preload) { + + rsetbit(RCC_APB1ENR, 2); // TIM4 enable + + rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode + rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set) + rsetbit(TIM4_CR1, 2); // only overflow generates update + + rwrite(TIM4_PSC, PRESCALER - 1); + rwrite(TIM4_ARR, preload); + rsetbit(TIM4_EGR, 0); + + ivt_set_gate(46, cnt_complete_handler, 0); + rsetbit(NVIC_ISER0, 30); // interupt 41 - 32 + + rsetbit(GPIOB_BSRR, 22); // + rsetbit(TIM4_DIER, 0); + rsetbit(TIM4_CR1, 0); + +} + +void run() { + + rsetbit(RCC_APB2ENR, 3); // GPIOB enable + rwrite(GPIOB_CRL, 0x47444444); // open drain general + + rsetbit(GPIOB_BSRR, 22); // high + tsensor_simple(2000); +// tsensor_output(580, 520); +// reset(); +// tsensor_simple(580); +} void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) { @@ -56,6 +149,7 @@ void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) { rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set) + rsetbit(TIM4_CR1, 2); // only overflow generates update rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz rwrite(TIM4_ARR, preload); // preload @@ -65,51 +159,56 @@ void tsensor_output(uint16_t preload, uint16_t compare/*, uint16_t pulses */) { rsetbit(TIM4_EGR, 0); // update generation rsetbit(TIM4_CR1, 3); // one pulse mode - rsetbitsfrom(TIM4_CCMR1, 4, 0x7); // PWM mode 1 + rsetbitsfrom(TIM4_CCMR1, 4, 0x6); // mode //rsetbit(TIM4_CCMR1, 3); // preload enable //rsetbit(TIM4_CR1, 7); // buffered - - rsetbit(TIM4_CCER, 0); // enable output channel 1 + rsetbit(TIM4_CCER, 0); // enable output channeli 1 + rsetbit(TIM4_CCER, 1); // active low rsetbit(TIM4_CR1, 0); // start counter /* INTERRUPTS */ - //ivt_set_gate(41, update_handler, 0); + ivt_set_gate(46, tmp_update_handler, 0); - //rsetbit(TIM4_DIER, 0); - //rsetbit(NVIC_ISER0, 25); // interupt 41 - 32 + rsetbit(TIM4_DIER, 1); + rsetbit(NVIC_ISER0, 30); // interupt 41 - 32 + } void tsensor_input(uint16_t preload) { - uint16_t timestamp; + //uint16_t timestamp; /* GPIO AND CLOCK */ - rsetbit(RCC_APB2ENR, 3); // GPIOB enable - rwrite(GPIOB_CRL, 0x44444444); // Input floating (default state) - rsetbit(RCC_APB1ENR, 2); // TIM4 enable + //rsetbit(RCC_APB2ENR, 3); // GPIOB enable + //rwrite(GPIOB_CRL, 0x44444444); // Input floating (default state) + //rsetbit(RCC_APB1ENR, 2); // TIM4 enable //rsetbitsfrom(TIM4_CR1, 5, 0x00); // edge-aligned mode //rclrbit(TIM4_CR1, 4); // upcounter (clrbit! not needed to set) rwrite(TIM4_PSC, PRESCALER - 1); // 1 MHz rwrite(TIM4_ARR, preload); // preload + + rsetbit(TIM4_EGR, 0); // update generation + rsetbit(TIM4_CCMR1, 0); // input on TI1 rsetbit(TIM4_CCMR1, 9); // another input TI2 - rsetbit(TIM4_CCER, 5); // other polarity, inverted + rsetbit(TIM4_CCER, 1); // other polarity for T1, inverted /* TODO: reg funct */ - rsetbit(TIM4_SMCR, 4); // 101 - rsetbit(TIM4_SMCR, 6); // 101 + rsetbit(TIM4_SMCR, 4); // OLD: 101, new Edge detector + rsetbit(TIM4_SMCR, 6); // - // rsetbit(TIM4_SMCR, 2); // RESET rising edge triggers counter and generates update - rsetbit(TIM4_SMCR, 2); // 110 - rsetbit(TIM4_SMCR, 1); // 110 + rsetbit(TIM4_SMCR, 2); // OLD: 110 + rsetbit(TIM4_SMCR, 1); + rsetbit(TIM4_SMCR, 0); + //rsetbit(TIM4_SMCR, 1); // 110 - rsetbit(TIM4_CR1, 3); // one pulse mode // NOTE: RESET after finised preload + //rsetbit(TIM4_CR1, 3); // one pulse mode // NOTE: RESET after finised preload // will catch multiple signal... can set fram rsetbit(TIM4_CCER, 0); // enable capture channel 1 (changed pos) diff --git a/include/drivers/at24c.h b/include/drivers/at24c.h new file mode 100644 index 0000000..ef1e09c --- /dev/null +++ b/include/drivers/at24c.h @@ -0,0 +1,7 @@ +#ifndef __AT24C_H +#define __AT24C_H + +extern void at24c_init(); +extern void at24c_run(); + +#endif diff --git a/include/drivers/tsensor.h b/include/drivers/tsensor.h index d22c068..ced6f5d 100644 --- a/include/drivers/tsensor.h +++ b/include/drivers/tsensor.h @@ -1,3 +1,4 @@ extern void tsensor_output(uint16_t, uint16_t/* , uint16_t */); extern void tsensor_input(uint16_t); +extern void run(); diff --git a/include/sys/mmap.h b/include/sys/mmap.h index 1c36be1..db6cf5c 100644 --- a/include/sys/mmap.h +++ b/include/sys/mmap.h @@ -69,6 +69,7 @@ #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 GPIOB_BSRR MEM_ADDR(0x40010C10) #define GPIOC_CRL MEM_ADDR(0x40011000) // led #define GPIOC_CRH MEM_ADDR(0x40011004) #define GPIOC_ODR MEM_ADDR(0x4001100C) diff --git a/main.c b/main.c index ff45998..b4f26ab 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include //void sleep() { @@ -62,10 +63,13 @@ void main() sysinfo(); - tsensor_input(5000); +// tsensor_input(5000); +// run(); led_init(); - rtc_init(); + at24c_init(); + at24c_run(); +// rtc_init(); // tm1637_init(); // tm1637_start(); -- 2.7.4