Got the encoder to work

+ added encoder mode support in timer driver
+ added external IRQ support in io driver
+ created 3D model for encoder cap
* tweaked ui lib for testing purposes
This commit is contained in:
Steins7 2020-02-02 22:20:10 +01:00
parent 3c7a09479c
commit 6baa7b0bbb
11 changed files with 211 additions and 133 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ bin
*tags *tags
*.taghl *.taghl
*.~lock* *.~lock*
*.stl

34
cad/encoder.scad Normal file
View File

@ -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);
}
}

View File

@ -87,15 +87,15 @@ void EXTI15_10_IRQHandler() {
} }
/* Definitions for EXTI configuration */ /* Definitions for EXTI configuration */
#define SYSCFG_EXTI_PA_MASK 0 enum io_exti_mask {
#define SYSCFG_EXTI_PB_MASK 1 SYSCFG_EXTI_PA_MASK = 0x0,
#define SYSCFG_EXTI_PC_MASK 2 SYSCFG_EXTI_PB_MASK = 0x1,
#define SYSCFG_EXTI_PD_MASK 3 SYSCFG_EXTI_PC_MASK = 0x2,
#define SYSCFG_EXTI_PE_MASK 4 SYSCFG_EXTI_PD_MASK = 0x3,
#define SYSCFG_EXTI_PH_MASK 7 SYSCFG_EXTI_PE_MASK = 0x4
};
int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint16_t pin_cfg, OnIO cb) {
int io_configure(GPIO_TypeDef *gpio, uint16_t pin, uint8_t pin_cfg, OnIO cb) {
// enable GPIOx subsystem clocking // enable GPIOx subsystem clocking
if (gpio == GPIOA) RCC->APB2ENR |= 1<<2; 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 // setup pin mask for crx registers
uint64_t pin_mask = 0; uint64_t pin_mask = 0;
for(int i=0; i<16; ++i) { for(int i=0; i<16; ++i) {
if((pin >> i) & 0x1) { if((pin >> i) & 0x1) pin_mask |= 0x1ll << 4*i;
pin_mask |= 0x1ll << 4*i;
}
} }
// clear previous data // 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 // set up the new configuration
crx = pin_mask * (pin_cfg & 0xF); crx = pin_mask * (pin_cfg & 0xF);
odr = pin_cfg & 0x10; odr = pin * ((pin_cfg & 0x10) >> 4);
gpio->CRH |= crx >> 32; gpio->CRH |= crx >> 32;
gpio->CRL |= crx & 0xFFFFFFFF; gpio->CRL |= crx & 0xFFFFFFFF;
gpio->BSRR |= odr; gpio->BSRR |= odr;
//if (!cb) return -1; //no callback attached
return 0;
//TODO manage alternate functions //TODO manage alternate functions
// if (pin_cfg & 0x3) return -1; //callback set, but not in input mode
// // manage IRQs //TODO allow IRQ reset
// // ************* Input GPIO + External IRQ ************* if (!cb) return 0; //no callback attached
//
// uint32_t port_mask = 0; if (pin_cfg & 0x7) return -1; //callback set, but not in input mode
// uint32_t pin_mask = 0;
// RCC->APB2ENR |= 0x1; //enable AFIO clocking
// if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK;
// else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK; // prepare mask
// else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK; uint8_t port_mask = 0;
// else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK; // uint32_t pin_mask = 0;
// else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK; if (gpio == GPIOA) port_mask = SYSCFG_EXTI_PA_MASK;
// else if (gpio == GPIOB) port_mask = SYSCFG_EXTI_PB_MASK;
// uint32_t bit_mask = 0x1; else if (gpio == GPIOC) port_mask = SYSCFG_EXTI_PC_MASK;
// else if (gpio == GPIOD) port_mask = SYSCFG_EXTI_PD_MASK;
// for (int i=0; i<16; i++) { else if (gpio == GPIOE) port_mask = SYSCFG_EXTI_PE_MASK;
// if (pin_mask & bit_mask) {
// // enable clock for SYSCFG, no need for EXTI (interface not clocked) // setup external IRQ lines
// RCC->APB2ENR = RCC->APB2ENR | (1<<14); uint16_t afio_mask;
// for(int i=0; i<4; ++i) {
// // configure pin Px_i (4 pin config per EXTICR[] register, 4 bits per pin) afio_mask = ((pin_mask & (0xFFFF << i)) >> i) * port_mask;
// // use port Px and bind Px_i --> EXTIi if(afio_mask) AFIO->EXTICR[i] |= afio_mask;
// // i>>2 = i/4 ; i & 0x3 = i%4 }
// gpio->EXTICR[i>>2] = (SYSCFG->EXTICR[i>>2] &
// ~(0x0000000F << ((i & 3)<<2))) | // clear pending IRQs on concerned lines
// (port_mask << ((i & 3)<<2)); EXTI->PR |= pin;
//
// // allow pin EXTIi to send an IRQ // configure IRQ options and masks
// EXTI->IMR = EXTI->IMR | bit_mask; EXTI->IMR |= pin;
// // not a wakeup event if(pin_cfg & 0x100) EXTI->RTSR |= pin;
// EXTI->EMR = EXTI->EMR & (~bit_mask); if(pin_cfg & 0x200) EXTI->FTSR |= pin; //in case both falling and rising
// //are set, both will be a trigger
// // Configure pin event IRQ on rising (RTSR)/falling (FTSR) edge (rising only here)
// if (pin_cfg & PIN_OPT_IRQ_EDGE_RISE) { // register IRQ callbacks
// EXTI->RTSR = EXTI->RTSR | bit_mask; for(int i=0; i<16; ++i) {
// } else { if((pin >> i) & 0x1) {
// EXTI->RTSR = EXTI->RTSR & (~bit_mask); io_cb[i] = cb;
// }
// // Setup NVIC
// if (pin_cfg & PIN_OPT_IRQ_EDGE_FALL) { switch (i) {
// EXTI->FTSR = EXTI->FTSR | bit_mask; case 0:
// } else { NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY);
// EXTI->FTSR = EXTI->FTSR & (~bit_mask); NVIC_EnableIRQ(EXTI0_IRQn);
// } break;
// case 1:
// io_cb[i] = cb; NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY);
// NVIC_EnableIRQ(EXTI1_IRQn);
// // reset any pending IRQ on PC13 break;
// EXTI->PR = bit_mask; case 2:
// NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY);
// // Setup NVIC NVIC_EnableIRQ(EXTI2_IRQn);
// switch (i) { break;
// case 0: case 3:
// NVIC_SetPriority(EXTI0_IRQn, EXTI0_IRQ_PRIORITY); NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY);
// NVIC_EnableIRQ(EXTI0_IRQn); NVIC_EnableIRQ(EXTI3_IRQn);
// break; break;
// case 1: case 4:
// NVIC_SetPriority(EXTI1_IRQn, EXTI1_IRQ_PRIORITY); NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY);
// NVIC_EnableIRQ(EXTI1_IRQn); NVIC_EnableIRQ(EXTI4_IRQn);
// break; break;
// case 2: case 5:
// NVIC_SetPriority(EXTI2_IRQn, EXTI2_IRQ_PRIORITY); case 6:
// NVIC_EnableIRQ(EXTI2_IRQn); case 7:
// break; case 8:
// case 3: case 9:
// NVIC_SetPriority(EXTI3_IRQn, EXTI3_IRQ_PRIORITY); NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY);
// NVIC_EnableIRQ(EXTI3_IRQn); NVIC_EnableIRQ(EXTI9_5_IRQn);
// break; break;
// case 4: case 10:
// NVIC_SetPriority(EXTI4_IRQn, EXTI4_IRQ_PRIORITY); case 11:
// NVIC_EnableIRQ(EXTI4_IRQn); case 12:
// break; case 13:
// case 5: case 14:
// case 6: case 15:
// case 7: NVIC_SetPriority(EXTI15_10_IRQn, EXTI15_10_IRQ_PRIORITY);
// case 8: NVIC_EnableIRQ(EXTI15_10_IRQn);
// case 9: break;
// NVIC_SetPriority(EXTI9_5_IRQn, EXTI9_5_IRQ_PRIORITY); default:
// NVIC_EnableIRQ(EXTI9_5_IRQn); return -1; //impossible to get there
// break;
// case 10: }
// case 11: }
// case 12: }
// case 13: return 0;
// 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;
//}
} }

View File

@ -70,11 +70,14 @@ enum io_conf {
// PIN_OPT_AF15 0xF // PIN_OPT_AF15 0xF
//}; //};
///* irq pin option */ //------------------------------------------------------------------------------
//#define PIN_OPT_IRQ_EDGE_RISE (1 << 12) /* GPIO IRQ conf definitons */
//#define PIN_OPT_IRQ_EDGE_FALL (2 << 12) enum io_irq_conf {
//#define PIN_OPT_IRQ_EDGE_BOTH (3 << 12) IO_IRQ_EDGE_RISE = (0x1 << 8),
// IO_IRQ_EDGE_FALL = (0x2 << 8),
IO_IRQ_EDGE_BOTH = (0x3 << 8)
};
typedef void (*OnIO)(); typedef void (*OnIO)();
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -85,7 +88,7 @@ typedef void (*OnIO)();
* function 'cb' if not NULL. * function 'cb' if not NULL.
* returns 0 if success * 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); OnIO cb);
/* io_read /* io_read

View File

@ -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 // disable JTAG, as it utilise needed pins, SWD remains usable in
// synchronous mode // synchronous mode
RCC->APB2ENR |= 0x1; RCC->APB2ENR |= 0x1; //enable AFIO clocking
AFIO->MAPR = (AFIO->MAPR & ~(0x8 << 24)) | 0x2 << 24; AFIO->MAPR = (AFIO->MAPR & ~(0x8 << 24)) | 0x2 << 24;
// configure the lcd control pins // 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) { void lcd_set_cursor(uint8_t col, uint8_t row) {
lcd_send_cmd(LCD_DDRAM_ADDR | (col + rows_offset[row])); lcd_send_cmd(LCD_DDRAM_ADDR | (col + rows_offset[row]));
} }

View File

@ -268,3 +268,38 @@ void timer_stop(TIM_TypeDef *tmr) {
tmr->CR1 &= !1; 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;
}

View File

@ -41,6 +41,9 @@ void timer_start(TIM_TypeDef *tmr);
*/ */
void timer_stop(TIM_TypeDef *tmr); void timer_stop(TIM_TypeDef *tmr);
//------------------------------------------------------------------------------
int timer_enc_init(TIM_TypeDef* tmr);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//#define PWM_CHANNEL_1 0 //#define PWM_CHANNEL_1 0
//#define PWM_CHANNEL_2 1 //#define PWM_CHANNEL_2 1

View File

@ -16,6 +16,7 @@ Clock_t sysclks;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/* static variables */ /* static variables */
int val = 0; int val = 0;
int count = 0;
uint16_t data = 0; uint16_t data = 0;
int16_t voltage = 0; int16_t voltage = 0;
int16_t temp = 0; int16_t temp = 0;
@ -24,7 +25,14 @@ int16_t temp = 0;
/* Timer IRQ */ /* Timer IRQ */
static void timeout_cb(void) { static void timeout_cb(void) {
io_write(GPIOC, val, PIN_13); io_write(GPIOC, val, PIN_13);
io_write(GPIOB, val, PIN_12);
val = !val; 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 // configure GPIO for LED
if(io_configure(GPIOC, PIN_13, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0)) if(io_configure(GPIOC, PIN_13, IO_MODE_OUTPUT | IO_OUT_PUSH_PULL, 0))
return 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(GPIOC, 1, PIN_13);
io_write(GPIOB, 1, PIN_12);
// configure GPIOS for temperature sensors // configure GPIOS for temperature sensors
if(io_configure(GPIOA, PIN_0 | PIN_1 | PIN_2 | PIN_3 | PIN_4 | PIN_5, 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_send_cmd(LCD_DISP_CTRL | LCD_CTRL_DISP_ON | LCD_CTRL_CUR_OFF |
LCD_CTRL_BLINK_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 // start timed interruption
timer_tick_init(TIM2, 1000, timeout_cb); timer_tick_init(TIM2, 1000, timeout_cb);
timer_start(TIM2); timer_start(TIM2);
@ -59,13 +78,15 @@ int main(void) {
// main loop // main loop
while(1){ while(1){
// update T1 // update T1
data = adc_read(ADC1, 0); //data = adc_read(ADC1, 0);
data -= adc_read(ADC1, 1); //data -= adc_read(ADC1, 1);
voltage = ((data*4) << 8)/4095; //voltage = ((data*4) << 8)/4095;
temp = ((voltage - 0x73) << 8)/0x9; //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 // update T2
data = adc_read(ADC1, 2); data = adc_read(ADC1, 2);

View File

@ -1,5 +1,10 @@
#include "ui.h" #include "ui.h"
static uint8_t temp_pos[][2] = {
{11, 0},
{ 2, 1},
{11, 1}};
void update_temp(uint8_t id, int16_t t) { void update_temp(uint8_t id, int16_t t) {
if(id > 2) return; //protect from overflow if(id > 2) return; //protect from overflow
@ -7,7 +12,7 @@ void update_temp(uint8_t id, int16_t t) {
// prepare data // prepare data
char str[16]; //longer, in case of error char str[16]; //longer, in case of error
t = t >> 8; //t = t >> 8;
// convert int into str // convert int into str
uint32_t nb = num2str(str, t, 10); uint32_t nb = num2str(str, t, 10);

View File

@ -19,14 +19,6 @@ enum temp {
T2 = 2 T2 = 2
}; };
/** temp_pos
* coords of the temprature ids
*/
static uint8_t temp_pos[][2] = {
{11, 0},
{ 2, 1},
{11, 1}};
/** update_temp /** update_temp
* update on the lcd the given value for the corresponding id * update on the lcd the given value for the corresponding id
*/ */

View File

@ -18,7 +18,7 @@ uint32_t num2str(char *s, int number, uint8_t base) {
*s='\0'; *s='\0';
// reverse string // reverse string
uint32_t cnt = s - p; int cnt = s - p;
char tmp; char tmp;
for(int i=0; i<cnt/2; ++i) { for(int i=0; i<cnt/2; ++i) {
tmp = p[i]; tmp = p[i];