--- /dev/null
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/7/25 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ *
+ * */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/mmap.h>
+#include <sys/robsys.h>
+
+#include <lib/regfunc.h>
+#include <lib/string.h>
+#include <lib/stdio.h>
+#include <lib/tinyprintf.h>
+
+#include <drivers/at24c.h>
+
+#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 */
+
+}
+
+
#include <drivers/tsensor.h>
-#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 */) {
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
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)