diff --git a/.gitignore b/.gitignore index 8c2cfda..fed8529 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ bin *tags *.taghl *.~lock* +*.stl diff --git a/cad/encoder.scad b/cad/encoder.scad new file mode 100644 index 0000000..76ae1a3 --- /dev/null +++ b/cad/encoder.scad @@ -0,0 +1,34 @@ +//$fn = 100; + +r = 12; +h = 12; + +center_r = 3.2; + +mol_r = 7; +mol_off = 6; + +difference() { + union() { + difference() { + cylinder(h=h, r=r, center=true); + translate([0,0,h/2]) + cylinder(h=15, r=center_r, center=true); + for(i=[0:45:359]) { + echo((r+mol_off*sin(i))); + translate([(r+mol_off)*cos(i),(r+mol_off) + *sin(i),0]) + cylinder(h=h, r=mol_r, center=true); + } + } + translate([3,0,0]) + cube([3,2*center_r,h], center=true); + } + difference() { + translate([0,0,0.7]) + cylinder(h=h, r=0.8*r, center=true); + translate([0,0,0.7]) + cylinder(h=h, r=1.4*center_r, center=true); + + } +} \ No newline at end of file diff --git a/src/drivers/io.c b/src/drivers/io.c index edb7aac..502002a 100644 --- a/src/drivers/io.c +++ b/src/drivers/io.c @@ -87,15 +87,15 @@ void EXTI15_10_IRQHandler() { } /* Definitions for EXTI configuration */ -#define SYSCFG_EXTI_PA_MASK 0 -#define SYSCFG_EXTI_PB_MASK 1 -#define SYSCFG_EXTI_PC_MASK 2 -#define SYSCFG_EXTI_PD_MASK 3 -#define SYSCFG_EXTI_PE_MASK 4 -#define SYSCFG_EXTI_PH_MASK 7 +enum io_exti_mask { + SYSCFG_EXTI_PA_MASK = 0x0, + SYSCFG_EXTI_PB_MASK = 0x1, + SYSCFG_EXTI_PC_MASK = 0x2, + SYSCFG_EXTI_PD_MASK = 0x3, + SYSCFG_EXTI_PE_MASK = 0x4 +}; - -int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) { +int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint16_t pin_cfg, OnIO cb) { // enable GPIOx subsystem clocking if (gpio == GPIOA) RCC->APB2ENR |= 1<<2; @@ -107,9 +107,7 @@ int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) { // setup pin mask for crx registers uint64_t pin_mask = 0; for(int i=0; i<16; ++i) { - if((pin >> i) & 0x1) { - pin_mask |= 0x1ll << 4*i; - } + if((pin >> i) & 0x1) pin_mask |= 0x1ll << 4*i; } // clear previous data @@ -121,111 +119,96 @@ int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) { // set up the new configuration crx = pin_mask * (pin_cfg & 0xF); - odr = pin_cfg & 0x10; + odr = pin * ((pin_cfg & 0x10) >> 4); gpio->CRH |= crx >> 32; gpio->CRL |= crx & 0xFFFFFFFF; gpio->BSRR |= odr; - //if (!cb) return -1; //no callback attached - - return 0; - //TODO manage alternate functions -// if (pin_cfg & 0x3) return -1; //callback set, but not in input mode -// -// // ************* Input GPIO + External IRQ ************* -// -// uint32_t port_mask = 0; -// uint32_t pin_mask = 0; -// -// if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK; -// else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK; -// else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK; -// else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK; -// else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK; -// -// uint32_t bit_mask = 0x1; -// -// for (int i=0; i<16; i++) { -// if (pin_mask & bit_mask) { -// // enable clock for SYSCFG, no need for EXTI (interface not clocked) -// RCC->APB2ENR = RCC->APB2ENR | (1<<14); -// -// // configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin) -// // use port Px and bind Px_i --> EXTIi -// // i>>2 = i/4 ; i & 0x3 = i%4 -// gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] & -// ~(0x0000000F << ((i & 3)<<2))) | -// (port_mask << ((i & 3)<<2)); -// -// // allow pin EXTIi to send an IRQ -// EXTI->IMR = EXTI->IMR | bit_mask; -// // not a wakeup event -// EXTI->EMR = EXTI->EMR & (~bit_mask); -// -// // Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here) -// if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) { -// EXTI->RTSR = EXTI->RTSR | bit_mask; -// } else { -// EXTI->RTSR = EXTI->RTSR & (~bit_mask); -// } -// -// if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) { -// EXTI->FTSR = EXTI->FTSR | bit_mask; -// } else { -// EXTI->FTSR = EXTI->FTSR & (~bit_mask); -// } -// -// io_cb[i] = cb; -// -// // reset any pending IRQ on PC13 -// EXTI->PR = bit_mask; -// -// // Setup NVIC -// switch (i) { -// case 0: -// NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI0_IRQn); -// break; -// case 1: -// NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI1_IRQn); -// break; -// case 2: -// NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI2_IRQn); -// break; -// case 3: -// NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI3_IRQn); -// break; -// case 4: -// NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI4_IRQn); -// break; -// case 5: -// case 6: -// case 7: -// case 8: -// case 9: -// NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI9_5_IRQn); -// break; -// case 10: -// case 11: -// case 12: -// case 13: -// case 14: -// case 15: -// NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY); -// NVIC_EnableIRQ(EXTI15_10_IRQn); -// break; -// default: -// return 0; -//} -//} -//bit_mask = bit_mask<<1; -//} + + // manage IRQs //TODO allow IRQ reset + if (!cb) return 0; //no callback attached + + if (pin_cfg & 0x7) return -1; //callback set, but not in input mode + + RCC->APB2ENR |= 0x1; //enable AFIO clocking + + // prepare mask + uint8_t port_mask = 0; + // uint32_t pin_mask = 0; + if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK; + else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK; + else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK; + else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK; + else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK; + + // setup external IRQ lines + uint16_t afio_mask; + for(int i=0; i<4; ++i) { + afio_mask = ((pin_mask & (0xFFFF << i)) >> i) * port_mask; + if(afio_mask) AFIO->EXTICR[i] |= afio_mask; + } + + // clear pending IRQs on concerned lines + EXTI->PR |= pin; + + // configure IRQ options and masks + EXTI->IMR |= pin; + if(pin_cfg & 0x100) EXTI->RTSR |= pin; + if(pin_cfg & 0x200) EXTI->FTSR |= pin; //in case both falling and rising + //are set, both will be a trigger + + // register IRQ callbacks + for(int i=0; i<16; ++i) { + if((pin >> i) & 0x1) { + io_cb[i] = cb; + + // Setup NVIC + switch (i) { + case 0: + NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI0_IRQn); + break; + case 1: + NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI1_IRQn); + break; + case 2: + NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI2_IRQn); + break; + case 3: + NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI3_IRQn); + break; + case 4: + NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI4_IRQn); + break; + case 5: + case 6: + case 7: + case 8: + case 9: + NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI9_5_IRQn); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY); + NVIC_EnableIRQ(EXTI15_10_IRQn); + break; + default: + return -1; //impossible to get there + + } + } + } + return 0; } diff --git a/src/drivers/io.h b/src/drivers/io.h index f2dd873..cad5be2 100644 --- a/src/drivers/io.h +++ b/src/drivers/io.h @@ -70,11 +70,14 @@ enum io_conf { // PIN_OPT_AF15 0xF //}; -///* irq pin option */ -//#define PIN_OPT_IRQ_EDGE_RISE (1 << 12) -//#define PIN_OPT_IRQ_EDGE_FALL (2 << 12) -//#define PIN_OPT_IRQ_EDGE_BOTH (3 << 12) -// +//------------------------------------------------------------------------------ +/* GPIO IRQ conf definitons */ +enum io_irq_conf { + IO_IRQ_EDGE_RISE = (0x1 << 8), + IO_IRQ_EDGE_FALL = (0x2 << 8), + IO_IRQ_EDGE_BOTH = (0x3 << 8) +}; + typedef void (*OnIO)(); //------------------------------------------------------------------------------ @@ -85,7 +88,7 @@ typedef void (*OnIO)(); * function 'cb' if not NULL. * returns 0 if success */ -int io_configure(GPIO_TypeDef *gpio, uint16_t pin_mask, uint8_t pin_cfg, +int io_configure(GPIO_TypeDef *gpio, uint16_t pin_mask, uint16_t pin_cfg, OnIO cb); /* io_read diff --git a/src/drivers/lcd.c b/src/drivers/lcd.c index f2638a2..99abdca 100644 --- a/src/drivers/lcd.c +++ b/src/drivers/lcd.c @@ -94,7 +94,7 @@ int lcd_init(TIM_TypeDef* tim, uint8_t col, uint8_t row) { // disable JTAG, as it utilise needed pins, SWD remains usable in // synchronous mode - RCC->APB2ENR |= 0x1; + RCC->APB2ENR |= 0x1; //enable AFIO clocking AFIO->MAPR = (AFIO->MAPR & ~(0x8 << 24)) | 0x2 << 24; // configure the lcd control pins @@ -182,3 +182,4 @@ void lcd_print_c(char c) { void lcd_set_cursor(uint8_t col, uint8_t row) { lcd_send_cmd(LCD_DDRAM_ADDR | (col + rows_offset[row])); } + diff --git a/src/drivers/timer.c b/src/drivers/timer.c index 9a1c82d..6c4cfdd 100644 --- a/src/drivers/timer.c +++ b/src/drivers/timer.c @@ -268,3 +268,38 @@ void timer_stop(TIM_TypeDef *tmr) { tmr->CR1 &= !1; } +//------------------------------------------------------------------------------ +int timer_enc_init(TIM_TypeDef* tmr) { + // enable timer + if (tmr == TIM1) { + RCC->APB2ENR |= 1<<11; + + } else if (tmr == TIM2) { + RCC->APB1ENR |= 1<<0; + + } else if (tmr == TIM3) { + RCC->APB1ENR |= 1<<1; + + } else if (tmr == TIM4) { + RCC->APB1ENR |= 1<<2; + + } else return -1; //no such timer + + //TODO set registers at reset value + + tmr->SMCR |= 0x1; //count on only one edge + tmr->ARR = (1 << 16)-1; + + // map inputs + tmr->CCMR1 |= 0x9; + tmr->CCMR1 |= 0x9 << 8; + + // enable input channels + tmr->CCER |= 0x1; + tmr->CCER |= 0x1 << 4; + + tmr->CR1 |= 0x1; //enable timer + + return 0; +} + diff --git a/src/drivers/timer.h b/src/drivers/timer.h index eb9b893..772a047 100644 --- a/src/drivers/timer.h +++ b/src/drivers/timer.h @@ -41,6 +41,9 @@ void timer_start(TIM_TypeDef *tmr); */ void timer_stop(TIM_TypeDef *tmr); +//------------------------------------------------------------------------------ +int timer_enc_init(TIM_TypeDef* tmr); + //------------------------------------------------------------------------------ //#define PWM_CHANNEL_1 0 //#define PWM_CHANNEL_2 1 diff --git a/src/main.c b/src/main.c index 2a1dc71..ce07d3b 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ Clock_t sysclks; //------------------------------------------------------------------------------ /* static variables */ int val = 0; +int count = 0; uint16_t data = 0; int16_t voltage = 0; int16_t temp = 0; @@ -24,7 +25,14 @@ int16_t temp = 0; /* Timer IRQ */ static void timeout_cb(void) { io_write(GPIOC, val, PIN_13); + io_write(GPIOB, val, PIN_12); val = !val; + data = adc_read(ADC1, 2); + data -= adc_read(ADC1, 3); +} + +static void enc_button_cb(void) { + count = !count; } //------------------------------------------------------------------------------ @@ -36,7 +44,11 @@ int main(void) { // configure GPIO for LED if(io_configure(GPIOC, PIN_13, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0)) return 0; + if(io_configure(GPIOB, PIN_12, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0)) + return 0; + io_write(GPIOC, 1, PIN_13); + io_write(GPIOB, 1, PIN_12); // configure GPIOS for temperature sensors if(io_configure(GPIOA, PIN_0 | PIN_1 | PIN_2 | PIN_3 | PIN_4 | PIN_5, @@ -52,6 +64,13 @@ int main(void) { lcd_send_cmd(LCD_DISP_CTRL | LCD_CTRL_DISP_ON | LCD_CTRL_CUR_OFF | LCD_CTRL_BLINK_OFF); + // configure encoder + io_configure(GPIOB, PIN_6 | PIN_7, IO_MODE_INPUT | IO_IN_FLOATING, 0); + timer_enc_init(TIM4); + + io_configure(GPIOB, PIN_8, IO_MODE_INPUT | IO_IN_PULL_UP | + IO_IRQ_EDGE_FALL, enc_button_cb); + // start timed interruption timer_tick_init(TIM2, 1000, timeout_cb); timer_start(TIM2); @@ -59,13 +78,15 @@ int main(void) { // main loop while(1){ // update T1 - data = adc_read(ADC1, 0); - data -= adc_read(ADC1, 1); + //data = adc_read(ADC1, 0); + //data -= adc_read(ADC1, 1); - voltage = ((data*4) << 8)/4095; - temp = ((voltage - 0x73) << 8)/0x9; + //voltage = ((data*4) << 8)/4095; + //temp = ((voltage - 0x73) << 8)/0x9; - update_temp(T1, temp); + uint32_t pin = io_read(GPIOB, PIN_8); + if(!pin) count = !count; + if(count) update_temp(T1, (int16_t)TIM4->CNT/2); // update T2 data = adc_read(ADC1, 2); diff --git a/src/ui.c b/src/ui.c index 6ac3e28..5a39df1 100644 --- a/src/ui.c +++ b/src/ui.c @@ -1,5 +1,10 @@ #include "ui.h" +static uint8_t temp_pos[][2] = { + {11, 0}, + { 2, 1}, + {11, 1}}; + void update_temp(uint8_t id, int16_t t) { if(id > 2) return; //protect from overflow @@ -7,7 +12,7 @@ void update_temp(uint8_t id, int16_t t) { // prepare data char str[16]; //longer, in case of error - t = t >> 8; + //t = t >> 8; // convert int into str uint32_t nb = num2str(str, t, 10); diff --git a/src/ui.h b/src/ui.h index 9ae58e7..fd40280 100644 --- a/src/ui.h +++ b/src/ui.h @@ -19,14 +19,6 @@ enum temp { T2 = 2 }; -/** temp_pos - * coords of the temprature ids - */ -static uint8_t temp_pos[][2] = { - {11, 0}, - { 2, 1}, - {11, 1}}; - /** update_temp * update on the lcd the given value for the corresponding id */ diff --git a/src/utils.c b/src/utils.c index 1d16eb4..f501625 100644 --- a/src/utils.c +++ b/src/utils.c @@ -18,7 +18,7 @@ uint32_t num2str(char *s, int number, uint8_t base) { *s='\0'; // reverse string - uint32_t cnt = s - p; + int cnt = s - p; char tmp; for(int i=0; i