added timer support, and incomplete keyboard system

This commit is contained in:
ayabusa 2024-04-01 18:32:34 +02:00
parent 60540437fb
commit d3d586b6d2
18 changed files with 184 additions and 3 deletions

View File

@ -19,6 +19,8 @@
"tuple": "cpp",
"main.h": "c",
"led.h": "c",
"stm32f730xx.h": "c"
"stm32f730xx.h": "c",
"keyboard.h": "c",
"gpio_helper.h": "c"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -59,6 +59,34 @@ void set_output_pin(uint8_t gpio_x, uint8_t pin, bool state){
}
}
bool read_input_pin(uint8_t gpio_x, uint8_t pin){
// Invert the IDR register since '0' means 'pressed'.
uint8_t idr_val = 0;
switch (gpio_x)
{
case GPIO_A:
idr_val = ~GPIOA->IDR;
break;
case GPIO_B:
idr_val = ~GPIOB->IDR;
break;
case GPIO_C:
idr_val = ~GPIOC->IDR;
break;
case GPIO_D:
idr_val = ~GPIOD->IDR;
break;
case GPIO_E:
idr_val = ~GPIOE->IDR;
break;
default:
break;
}
return idr_val & (1 << pin);
}
void enable_gpio_x_rcc(uint8_t gpio_x){
switch (gpio_x)
{

View File

@ -17,6 +17,7 @@
#define GPIO_E 4
void set_output_pin(uint8_t gpio_x, uint8_t pin, bool state);
bool read_input_pin(uint8_t gpio_x, uint8_t pin);
void enable_gpio_x_rcc(uint8_t gpio_x);
#endif

View File

@ -0,0 +1,74 @@
/* The keyboard is a matrix that is laid out as follow:
* (K_B2 and K_B3 are respectively specific to N0100 and N0110
*
* | PC0 | PC1 | PC2 | PC3 | PC4 | PC5 |
* -----+------+------+------+------+------+------+
* PE0 | K_A1 | K_A2 | K_A3 | K_A4 | K_A5 | K_A6 |
* -----+------+------+------+------+------+------+
* PE1 | K_B1 |(K_B2)|(K_B3)| | | |
* -----+------+------+------+------+------+------+
* PE2 | K_C1 | K_C2 | K_C3 | K_C4 | K_C5 | K_C6 |
* -----+------+------+------+------+------+------+
* PE3 | K_D1 | K_D2 | K_D3 | K_D4 | K_D5 | K_D6 |
* -----+------+------+------+------+------+------+
* PE4 | K_E1 | K_E2 | K_E3 | K_E4 | K_E5 | K_E6 |
* -----+------+------+------+------+------+------+
* PE5 | K_F1 | K_F2 | K_F3 | K_F4 | K_F5 | |
* -----+------+------+------+------+------+------+
* PE6 | K_G1 | K_G2 | K_G3 | K_G4 | K_G5 | |
* -----+------+------+------+------+------+------+
* PE7 | K_H1 | K_H2 | K_H3 | K_H4 | K_H5 | |
* -----+------+------+------+------+------+------+
* PE8 | K_I1 | K_I2 | K_I3 | K_I4 | K_I5 | |
* -----+------+------+------+------+------+------|
*
* We decide to drive the rows (PE0-8) and read the columns (PC0-5).
*
* To avoid short-circuits, the pins E0-E8 will not be standard outputs but
* only open-drain. Open drain means the pin is either driven low or left
* floating.
* When a user presses multiple keys, a connection between two rows can happen.
* If we don't use open drain outputs, this situation could trigger a short
* circuit between an output driving high and another driving low.
*
* If the outputs are open-drain, this means that the input must be pulled up.
* So if the input reads "1", this means the key is in fact *not* pressed, and
* if it reads "0" it means that there's a short to an open-drain output. Which
* means the corresponding key is pressed.
*/
#include "keyboard.h"
const uint8_t number_of_rows = 9;
const uint8_t number_of_columns = 6;
void keyboard_init(){
for (int i = 0; i < number_of_rows; i++){
// setup rows (output open drain)
GPIOA->MODER &= ~(0x3 << (i*2));
GPIOA->MODER |= (0x1 << (i*2));
GPIOA->OTYPER |= (1 << i);
}
for (int i = 0; i < number_of_columns; i++){
// setup columns (input pullup)
GPIOC->MODER &= ~(0x3 << (i*2));
GPIOC->PUPDR &= ~(0x3 << (i*2));
GPIOC->PUPDR |= (0x1 << (i*2));
}
}
bool keyboard_scan(){
set_output_pin(GPIO_A, 6, true);
bool key_state = read_input_pin(GPIO_C, 3);
return key_state;
// A LOT TODO
}
void activate_row(uint8_t row_nb){
// set all row to 0 and then reenable selected row
for(int i =0; i < number_of_rows; i++){
set_output_pin(GPIO_A, i, true);
}
set_output_pin(GPIO_A, row_nb, false);
us_wait(100);
}

View File

@ -0,0 +1,27 @@
/** @file keyboard.h
*
* @brief All action related to keyboard scan
*
*/
#ifndef KEYBOARD_H
#define KEYBOARD_H
enum PIN_ROW {
A = 1,
B = 0,
C = 2,
D = 3,
E = 4,
F = 5,
G = 6,
H = 7,
I = 8
};
#include "gpio_helper.h"
void keyboard_init();
bool keyboard_scan();
#endif

View File

@ -4,4 +4,9 @@ void laplace_init(){
// Enable the GPIO peripheral in RCC.
enable_gpio_x_rcc(GPIO_B);
led_init();
//col (in)
enable_gpio_x_rcc(GPIO_C);
//row (out)
enable_gpio_x_rcc(GPIO_A);
keyboard_init();
}

View File

@ -9,6 +9,7 @@
#include "gpio_helper.h"
#include "led.h"
#include "keyboard.h"
void laplace_init();

View File

@ -0,0 +1,13 @@
#include "time.h"
void us_wait(uint8_t micro_seconds) {
for (volatile uint32_t i=0; i<loops_per_microsecond*micro_seconds; i++) {
__asm volatile("nop");
}
}
void ms_wait(uint16_t milli_seconds) {
for (volatile uint32_t i=0; i<loops_per_millisecond*milli_seconds; i++) {
__asm volatile("nop");
}
}

View File

@ -0,0 +1,18 @@
/** @file time.h
*
* @brief Handle timer operation
*
*/
#ifndef TIME_H
#define TIME_H
#define loops_per_microsecond 1
#define loops_per_millisecond 960
#include "stdint.h"
void us_wait(uint8_t micro_seconds);
void ms_wait(uint16_t milli_seconds);
#endif

View File

@ -1,8 +1,18 @@
#include "main.h"
// this is our main function, I separated it from the c++ code because I don't like this language
main_entry(){
void main_entry(){
// init all the peripherals
laplace_init();
set_led_all(true);
ms_wait(2000);
set_led_green(true);
while (1)
{
/*if(keyboard_scan()){
set_led_green(true);
}else{
set_led_green(false);
}*/
}
}

View File

@ -9,6 +9,8 @@
#include "Laplace/laplace.h"
#include "Laplace/led.h"
#include "Laplace/keyboard.h"
#include "Laplace/time.h"
void main_entry();