182 lines
5.9 KiB
C
182 lines
5.9 KiB
C
#include <stm32f4xx.h>
|
|
#include <carme_io2.h>
|
|
#include "io.h"
|
|
|
|
// Local functions
|
|
typedef struct pin_s {
|
|
GPIO_TypeDef* GPIO;
|
|
uint16_t pinmask;
|
|
bool input;
|
|
} pin_t;
|
|
|
|
static void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input);
|
|
static bool pin_get(pin_t* pin);
|
|
static void pin_set(pin_t* pin, bool status);
|
|
static void pin_toggle(pin_t* pin);
|
|
|
|
// Local variables
|
|
static pin_t pin_t0;
|
|
static pin_t pin_t1;
|
|
static pin_t pin_t2;
|
|
static pin_t pin_t3;
|
|
static pin_t pin_s0;
|
|
static pin_t pin_s1;
|
|
static pin_t pin_s2;
|
|
static pin_t pin_s3;
|
|
static pin_t pin_s4;
|
|
static pin_t pin_s5;
|
|
static pin_t pin_s6;
|
|
static pin_t pin_s7;
|
|
static uint8_t new = 0;
|
|
static uint8_t old = 0;
|
|
static volatile uint8_t edg = 0;
|
|
|
|
void pin_create(pin_t* pin, GPIO_TypeDef* GPIO, uint8_t pinnr, bool input) {
|
|
GPIO_InitTypeDef gi; // Create gpio init structure
|
|
GPIO_StructInit(&gi); // Fill gpio init structure with defaults
|
|
|
|
gi.GPIO_Pin = 1 << pinnr; // create bitmask out of pin number
|
|
|
|
if(input) { // If the pin is set to be an input
|
|
gi.GPIO_Mode = GPIO_Mode_IN; // Set mode to input
|
|
gi.GPIO_OType = GPIO_OType_OD; // Set type to open drain
|
|
gi.GPIO_PuPd = GPIO_PuPd_UP; // Set a pullup
|
|
} else {
|
|
gi.GPIO_Mode = GPIO_Mode_OUT; // Set mode to output
|
|
gi.GPIO_OType = GPIO_OType_PP; // Set type to pushpull
|
|
gi.GPIO_PuPd = GPIO_PuPd_NOPULL; // Set no pullup
|
|
}
|
|
|
|
GPIO_Init(GPIO,&gi); // Update the GPIO configuration
|
|
|
|
pin->GPIO=GPIO; // Set the gpiopin in the pin structure
|
|
pin->pinmask=0x01<<pinnr; // Insert the pinmask
|
|
pin->input = input; // Store the input information
|
|
}
|
|
|
|
bool pin_get(pin_t* pin) {
|
|
if(pin->input) { // If the pin is an input
|
|
return GPIO_ReadInputDataBit(pin->GPIO,pin->pinmask); // Read its value
|
|
} else { // If the pin is an output
|
|
return GPIO_ReadOutputDataBit(pin->GPIO,pin->pinmask); // Read its set value
|
|
}
|
|
}
|
|
|
|
void pin_set(pin_t* pin, bool status) {
|
|
if(!pin->input) { // If the pin isn't an input
|
|
GPIO_WriteBit(pin->GPIO,pin->pinmask,status); // Set its value accordingly
|
|
}
|
|
}
|
|
|
|
void pin_toggle(pin_t* pin) {
|
|
if(!pin->input) { // If the pin isn't an input
|
|
pin_set(pin,!pin_get(pin)); // Toggle its value
|
|
}
|
|
}
|
|
|
|
void io_init(void){
|
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC,ENABLE); // Enable gpio clock source
|
|
// Create player pins
|
|
pin_create(&pin_t0, GPIOC, 7, true); // create pin_t0
|
|
pin_create(&pin_t1, GPIOB, 15, true); // create pin_t1
|
|
pin_create(&pin_t2, GPIOB, 14, true); // create pin_t2
|
|
pin_create(&pin_t3, GPIOI, 0, true); // create pin_t3
|
|
|
|
// TODO: Create color choosing pins
|
|
/*pin_create(&pin_s0, GPIO, , true); // create pin_t0
|
|
pin_create(&pin_s1, GPIO, , true); // create pin_t1
|
|
pin_create(&pin_s2, GPIO, , true); // create pin_t2
|
|
pin_create(&pin_s3, GPIO, , true); // create pin_t3
|
|
pin_create(&pin_s4, GPIO, , true); // create pin_t0
|
|
pin_create(&pin_s5, GPIO, , true); // create pin_t1
|
|
pin_create(&pin_s6, GPIO, , true); // create pin_t2
|
|
pin_create(&pin_s7, GPIO, , true); // create pin_t3*/
|
|
|
|
|
|
}
|
|
|
|
void io_process(void) {
|
|
new = pin_get(&pin_t0) |
|
|
pin_get(&pin_t1) << 1 |
|
|
pin_get(&pin_t2) << 2 |
|
|
pin_get(&pin_t3) << 3;
|
|
|
|
edg |= (new ^ old) & new; // detect positive edge
|
|
old = new;
|
|
}
|
|
|
|
bool io_button_has_edge(uint8_t btnnumber) {
|
|
uint8_t bm = (1 << btnnumber); // create bitmask
|
|
bool status = ((edg & bm) > 0); // check if button is pressed
|
|
|
|
if(status){
|
|
edg &= ~bm; // clear edge bit
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
void init_adc(){
|
|
/*
|
|
//Enable the peripheral clock of GPIOB
|
|
//This has been already done in the startup code
|
|
//Page 239/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
RCC->AHB1ENR |= RCC_AHB1Periph_GPIOB;
|
|
//Choose the working mode of PB0 with the GPIO port mode register
|
|
//Page 279/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
GPIOB->MODER &= ~GPIO_MODER_MODER0;
|
|
GPIOB->MODER |= GPIO_Mode_AN;
|
|
//Configure the GPIO port pull-up/pull-down register for PB0
|
|
//Page 282/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR0;
|
|
GPIOB->PUPDR |= GPIO_PuPd_UP;
|
|
|
|
//Initialize the ADC
|
|
//Enable the peripheral clock of the ADC
|
|
//Page 245/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
RCC->APB2ENR |= RCC_APB2Periph_ADC;
|
|
//Configure ADC1: scan conversion mode and resolution
|
|
//Set SCAN bit according to ADC_ScanConvMode value
|
|
//Set RES bit according to ADC_Resolution value
|
|
// Page 416/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
ADC1->CR1 = ADC_Resolution_10b;
|
|
// Configure ADC1: regular channel sequence length
|
|
// Set L bits according to ADC_NbrOfConversion value
|
|
// Page 422/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
ADC1->SQR1 = 0;
|
|
// Set the ADON bit to enable the ADC
|
|
// Page 418/1718 of "RM0090 Reference Reference Manual (October 2014)"
|
|
ADC1->CR2 = ADC_CR2_ADON;
|
|
*/
|
|
}
|
|
|
|
uint16_t read_adc(){
|
|
uint16_t value = 0;
|
|
/*
|
|
// Specify the sample time for the conversion
|
|
ADC1->SMPR2 &= SMPR1_SMP_SET << (3 * ADC_Channel_8);
|
|
ADC1->SMPR2 |= ADC_SampleTime_15Cycles << (3 * ADC_Channel_8);
|
|
// Set the channel 8 as the first conversion in the ADC reg seq register
|
|
ADC1->SQR3 &= ~SQR3_SQ_SET;
|
|
ADC1->SQR3 |= ADC_Channel_8;
|
|
// Start the conversion
|
|
ADC1->CR2 |= ADC_CR2_SWSTART;
|
|
// Wait until the conversion has been done
|
|
while( (ADC1->SR & ADC_FLAG_EOC) == 0 );
|
|
// Read the value
|
|
value = ADC1->DR;
|
|
value &= 0x03FF;
|
|
*/
|
|
return value;
|
|
}
|
|
|
|
uint16_t get_player_color(player_t* player, bool first_player){
|
|
if(!first_player){
|
|
// Read bit 0-3 and calculate color
|
|
}else{
|
|
// Read but 4-7 and calculate color
|
|
}
|
|
|
|
return 0;
|
|
}
|