// EasyNucleoIO.h // David_Harris@hmc.edu 19 March 2017 // This library provides an Arduino-style interface to control I/O // devices on a STM32F042K6 device on a STM Nucleo board. // The STM NUCLEO-F042K6 boad maps the STM32 pins to Arduino pin names // as given in Table 9 of the datasheet: // Arduino Pin Name STM32 Pin // D0 PA10 // D1 PA9 // D2 PA12 // D3 PB0 // D4 PB7 // D5 PB6 // D6 PB1 // D7 PF0 // D8 PF1 // D9 PA8 // D10 PA11 // D11 PB5 // D12 PB4 // D13 PB3 (on-board green LED) // A0 (D14) PA0 // A1 (D15) PA1 // A2 (D16) PA3 // A3 (D17) PA4 // A4 (D18) PA5 // A5 (D19) PA6 // A6 (D20) PA7 // A7 (D21) PA2 #include // Mapping of Dx pins to STM pins. // 15:0 are STM PA15:0 // 23:16 are STM PB7:0 // 33:32 are STM PF1:0 // ARDUINO Pin Modes #define INPUT 0 #define OUTPUT 1 // Delay constants #define COUNTSPERMS 898 ///////////////////////////////////////////////////////////////////// // Helper functions for converting pin numbers ///////////////////////////////////////////////////////////////////// int digitalPinMapping[22] = {10, 9, 12, 16, 23, 22, 17, 32, 33, 8, 11, 21, 20, 19, 0, 1, 3, 4, 5, 6, 7, 2}; int analogPinMapping[8] = {0, 1, 3, 4, 5, 6, 7, 2}; GPIO_TypeDef* pinToReg(int pin) { int p = digitalPinMapping[pin]; if (p < 16) return GPIOA; else if (p < 32) return GPIOB; else return GPIOF; } int pinToOffset(int pin) { int p = digitalPinMapping[pin]; return p % 16; } ///////////////////////////////////////////////////////////////////// // Initialization // This function must be called before any others are used ///////////////////////////////////////////////////////////////////// void EasyNucleoIOInit(void) { //Clocks: //enable clock for GPIOA, and GPIOB RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOFEN; //enable clock to SPI1 RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; } ///////////////////////////////////////////////////////////////////// // GPIO Functions ///////////////////////////////////////////////////////////////////// void pinMode(int pin, int function) { GPIO_TypeDef *gpio = pinToReg(pin); int offset = pinToOffset(pin)*2; gpio->MODER &= ~((3 & ~function) << offset); gpio->MODER |= ((3 & function) << offset); } void digitalWrite(int pin, int val) { GPIO_TypeDef *gpio = pinToReg(pin); int offset = pinToOffset(pin); if (val) gpio->ODR |= (1 << offset); else gpio->ODR &= ~(1 << offset); } int digitalRead(int pin) { GPIO_TypeDef *gpio = pinToReg(pin); int offset = pinToOffset(pin); return (gpio->IDR >> offset) & 0x1; } ///////////////////////////////////////////////////////////////////// // Delay Functions ///////////////////////////////////////////////////////////////////// void delayLoop(int ms) { // declare counter volatile so it isn't optimized away // countsperms empirically determined such that delayLoop(100) waits 100 ms volatile int i = COUNTSPERMS * ms; while (i--); // count down time }