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:
parent
3c7a09479c
commit
6baa7b0bbb
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ bin
|
||||
*tags
|
||||
*.taghl
|
||||
*.~lock*
|
||||
*.stl
|
||||
|
||||
34
cad/encoder.scad
Normal file
34
cad/encoder.scad
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
203
src/drivers/io.c
203
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;
|
||||
|
||||
// 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;
|
||||
//
|
||||
// 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;
|
||||
//}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]));
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
31
src/main.c
31
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);
|
||||
|
||||
7
src/ui.c
7
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);
|
||||
|
||||
8
src/ui.h
8
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
|
||||
*/
|
||||
|
||||
@ -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<cnt/2; ++i) {
|
||||
tmp = p[i];
|
||||
|
||||
Reference in New Issue
Block a user