From 191f9ab47131e876b492e2f59f188e8042fbe1b7 Mon Sep 17 00:00:00 2001 From: Robin Krens Date: Fri, 13 Sep 2019 17:28:21 +0700 Subject: [PATCH] mk450: x and y axis basic implementation --- Makefile | 2 +- README.md | 2 +- drivers/mk450_joystick.c | 115 +++++++++++++++++++++++++++++++++++++++ include/drivers/mk450_joystick.h | 9 +++ include/sys/mmap.h | 28 +++++++++- ivt.c | 2 +- main.c | 18 ++++-- rtc.c | 10 +++- 8 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 drivers/mk450_joystick.c create mode 100644 include/drivers/mk450_joystick.h diff --git a/Makefile b/Makefile index 949e287..3eb5eed 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 at24c.o +_DRIVERS = uart.o tm1637.o led.o tsensor.o at24c.o mk450_joystick.o DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS)) LDIR = obj/lib diff --git a/README.md b/README.md index 8e7ec46..42da980 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ port this code to any Cortex M0/M3/M4/M7 board. * LED segment display: drivers/tm1637.c [COMPLETED] * Temperature sensor: drivers/tsensor.c [COMPLETED] * OLED display [PLANNED] - * Joystick [PLANNED] + * Joystick: drivers/mk450_joystick.c [IN PROGRESS] * Memory Management [IN PROGRESS] -- FILE: lib/pool.c * User Mode [PLANNED] * System Call PendV implementation [PLANNED] diff --git a/drivers/mk450_joystick.c b/drivers/mk450_joystick.c new file mode 100644 index 0000000..a4c01d3 --- /dev/null +++ b/drivers/mk450_joystick.c @@ -0,0 +1,115 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/9/11 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Dual Axis XY Joystick controller + * + * $USAGE$ + * + * */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +/* X and Y values of the joystick + * Updated continiously */ +uint16_t xyvalues[2] = {0,0}; + + +/* Y return values is mV + * ~2500 mv means y is idle state + * ~0 far left + * ~5000 far right */ +uint16_t mk450_gety() { + + int y = xyvalues[1]; + return y; +} + +/* X return values (see y) */ +uint16_t mk450_getx() { + + int x = xyvalues[0]; + return x; +} + +void mk450_init() { + + // clock prescaler + rsetbitsfrom(RCC_CFGR, 14, 0x3); + + rsetbit(RCC_APB2ENR, 2); // enable GPIOA + rwrite(GPIOA_CRL, 0x44444400); // analog input on GPIOA0 + rsetbit(RCC_APB2ENR, 9); // enable ADC1 + + /* DMA init */ + rsetbit(RCC_AHBENR, 0); // enable clock on DMA1 + rwrite(DMA_CPAR1, (uint32_t) ADC1_DR); + rwrite(DMA_CMAR1, xyvalues); + rwrite(DMA_CNDTR1, 2); // two values X and Y values + rsetbitsfrom(DMA_CCR1, 8, 0x1); // 16-bit + rsetbitsfrom(DMA_CCR1, 10, 0x1); // 16-bit + rsetbit(DMA_CCR1, 7); // memory increment mode + rsetbit(DMA_CCR1, 5); // circular mode + + /* DMA Interrupt */ + //ivt_set_gate(27, dma_interrupt, 0); + //rsetbit(NVIC_ISER0, 11); + //rsetbit(DMA_CCR1, 1); + + rsetbit(DMA_CCR1, 0); // channel enable + + /* Scan mode for two input channels*/ + rsetbitsfrom(ADC1_SQR1, 20, 0x1); // 2 channels + rsetbitsfrom(ADC1_SQR3, 0, 0x0); // ADC1_IN0 + rsetbitsfrom(ADC1_SQR3, 5, 0x1); // ADC1_IN1 + rsetbit(ADC1_CR1, 8); // scan mode + + rsetbitsfrom(ADC1_CR2, 17, 0x7); // swstart config + rsetbit(ADC1_CR2, 20); // trigger enable + rsetbitsfrom(ADC1_SMPR2, 0, 0x7); // 237 cycles + rsetbitsfrom(ADC1_SMPR2, 3, 0x7); // 237 cycles + rsetbit(ADC1_CR2, 1); // continious mode + + /* Calibrate */ + rsetbit(ADC1_CR2, 2); // calibrate + _block(500); + + /* Interrupt End of conversion (group!) */ + //ivt_set_gate(34, eoc_interrupt, 0); + //rsetbit(NVIC_ISER0, 18); + //rsetbit(ADC1_CR1, 5); + + rsetbit(ADC1_CR2, 8); // enable DMA + rsetbit(ADC1_CR2, 0); // enable ADC + rsetbit(ADC1_CR2, 22); // swstart go! + +} + +/* End of conversion interrupt */ +void * eoc_interrupt() { + printf("SR1: %p\n", *ADC1_SR1); + printf("CR1: %p\n", *ADC1_CR1); + printf("CR2: %p\n", *ADC1_CR2); + printf("DR: %p\n", *ADC1_DR); // reading data registers clear interrupt flag +} + +/* DMA interrupt */ +void * dma_interrupt() { + printf("DMA Interrupt!\n"); + printf("Values: %x:%x\n", xyvalues[0], xyvalues[1] ); + rsetbit(DMA_IFCR, 1); +} diff --git a/include/drivers/mk450_joystick.h b/include/drivers/mk450_joystick.h new file mode 100644 index 0000000..5604626 --- /dev/null +++ b/include/drivers/mk450_joystick.h @@ -0,0 +1,9 @@ +#ifndef __MK450_JOYSTICK_H +#define __MK450_JOYSTICK_H + +extern void mk450_init(); +extern uint16_t mk450_getx(); +extern uint16_t mk450_gety(); + +#endif + diff --git a/include/sys/mmap.h b/include/sys/mmap.h index d33b17e..4275bc7 100644 --- a/include/sys/mmap.h +++ b/include/sys/mmap.h @@ -5,7 +5,7 @@ * Initial version * * $DESCRIPTION$ - * Memory map for the Cortex-A3 + * Memory map for the Cortex-M3 * Implementations vary among manufacturers. This one is * a STM32F013RC6. Addresses of peripherals vary amongst * manufacturers of boards with similar chips @@ -45,6 +45,7 @@ /* NESTED VECTOR INTERRUPT CONTROL REGISTER */ #define NVIC_ISER0 MEM_ADDR(0xE000E100) // interrupt set enable register #define NVIC_ISER1 MEM_ADDR(0xE000E104) // interrupt set enable register +#define NVIC_ISER2 MEM_ADDR(0xE000E108) // interrupt set enable register /* SYSTICK REGISTER */ #define STK_CTRL MEM_ADDR(0xE000E010) @@ -58,6 +59,7 @@ /* SYSTEM CONTROL REGISTER */ #define SYSCTRL_RCC MEM_ADDR(0x40021000) +#define RCC_AHBENR MEM_ADDR(0x40021014) // enable DMA1 #define RCC_APB1ENR MEM_ADDR(0x4002101C) // register to enable I2C #define RCC_APB1RSTR MEM_ADDR(0x40021010) // register to reset I2C #define RCC_APB2ENR MEM_ADDR(0x40021018) // register to enable USART1 @@ -68,6 +70,7 @@ #define GPIOPA_AFSEL MEM_ADDR(0x40004420) #define GPIOA_CRH MEM_ADDR(0x40010804) // for USART1 +#define GPIOA_CRL MEM_ADDR(0x40010800) // for ADC1 #define GPIOA_ODR MEM_ADDR(0x4001080C) #define GPIOB_CRL MEM_ADDR(0x40010C00) // low register (!) for I2C1 #define GPIOB_BSRR MEM_ADDR(0x40010C10) @@ -113,6 +116,7 @@ /* BACKUP (CALIBR) REGISTERS */ #define BKP_RTCCR MEM_ADDR(0x40006C2C) // RTC Calibration +/* TIMERS */ #define TIM4_CR1 MEM_ADDR(0x40000800) #define TIM4_RCR MEM_ADDR(0x40000830) #define TIM4_ARR MEM_ADDR(0x4000082C) @@ -126,3 +130,25 @@ //#define TIM1_BDTR MEM_ADDR(0x40000844) #define TIM4_CCMR1 MEM_ADDR(0x40000818) #define TIM4_DIER MEM_ADDR(0x4000080C) + +/* ANALOG TO DIGITAL CONVERSION + * (ADC1) */ +#define ADC1_SR1 MEM_ADDR(0x40012400) +#define ADC1_CR1 MEM_ADDR(0x40012404) +#define ADC1_CR2 MEM_ADDR(0x40012408) +#define ADC1_SMPR2 MEM_ADDR(0x40012410) +#define ADC1_HTR MEM_ADDR(0x40012424) +#define ADC1_LTR MEM_ADDR(0x40012428) +#define ADC1_SQR1 MEM_ADDR(0x4001242C) +#define ADC1_SQR3 MEM_ADDR(0x40012434) +#define ADC1_DR MEM_ADDR(0x4001244C) + +/* DMA1 Channel 1 */ +#define DMA_IFCR MEM_ADDR(0x40020004) +#define DMA_CCR1 MEM_ADDR(0x40020008) +#define DMA_CPAR1 MEM_ADDR(0x40020010) +#define DMA_CMAR1 MEM_ADDR(0x40020014) +#define DMA_CNDTR1 MEM_ADDR(0x4002000C) + + + diff --git a/ivt.c b/ivt.c index d62a8dd..a271487 100644 --- a/ivt.c +++ b/ivt.c @@ -124,7 +124,7 @@ void * dummy_isr( struct interrupt_frame * frame ) { printf("PC:%p\n",frame->pc); printf("PSR:%p\n",frame->psr); - //for(;;); + for(;;); } /* Initialize interrupt vector */ diff --git a/main.c b/main.c index d2087d7..2526963 100644 --- a/main.c +++ b/main.c @@ -23,9 +23,10 @@ #include #include -#include +//#include //#include -#include +//#include +#include void main() { @@ -43,6 +44,7 @@ void main() * by the more accurate RTC. systick_init(); */ + /* Set up a very small libc library */ init_printf(NULL, putc); @@ -54,7 +56,7 @@ void main() led_init(); /* Real time clock */ - //rtc_init(); + rtc_init(); /* Eeprom Driver eeprom_at24c_init(); @@ -64,17 +66,21 @@ void main() /* LED Segment Driver */ //tm1637_init(); + /* ASM Blocking routine */ //for (int i = 0; i < 1000; i++) // _block(10000); - /* TEMP SENSOR */ + /* TEMP SENSOR tsensor_printid(); uint16_t temp = tsensor_get_temp(); - printf("Current temperature: %d °C\n", temp); + printf("Current temperature: %d °C\n", temp); */ + + /* ADC Joystick module */ + mk450_init(); /* Start up terminal */ terminal(); - + /* Should not be here, endless loop */ for(;;) { diff --git a/rtc.c b/rtc.c index 7765046..5490b22 100644 --- a/rtc.c +++ b/rtc.c @@ -27,6 +27,7 @@ #include #include +#include /* This handler is invoked each clock tick. I've included two examples @@ -58,9 +59,12 @@ void * rtc_handler() { } */ // Simple LED blink - uint32_t curr = *RTC_CNTL; - int even = *RTC_CNTL % 2; - (!even) ? led_off() : led_on(); + //uint32_t curr = *RTC_CNTL; + //int even = *RTC_CNTL % 2; + //(!even) ? led_off() : led_on(); + + printf("X: %x\n", mk450_getx()); + printf("Y: %x\n", mk450_gety()); rclrbit(RTC_CRL, 0); /* clear interrupt flag */ } -- 2.7.4