Skip to content
Snippets Groups Projects
Unverified Commit a37c90dc authored by CNLohr's avatar CNLohr Committed by GitHub
Browse files

Merge pull request #38 from recallmenot/master

added GPIO example
parents 8feee5c9 44c195df
No related branches found
No related tags found
No related merge requests found
// blink, but with arduino-like HAL
// Could be defined here, or in the processor defines.
#define SYSTEM_CORE_CLOCK 48000000
#include "ch32v003fun.h"
#include "wiring_digital.h"
#include <stdio.h>
#define APB_CLOCK SYSTEM_CORE_CLOCK
uint32_t count;
int main() {
SystemInit48HSI();
// Enable GPIO ports
enablePort(port_C);
enablePort(port_D);
for (int i = pin_C0; i <= pin_C7; i++) {
pinMode(i, pinMode_O_pushPull);
}
// GPIO D4 Push-Pull
pinMode(pin_D4, pinMode_O_pushPull);
while (1) {
// Turn on pins
digitalWrite(pin_C0, high);
digitalWrite(pin_D4, high);
Delay_Ms(250);
// Turn off pins
digitalWrite(pin_C0, low);
digitalWrite(pin_D4, low);
Delay_Ms(250);
for (int i = pin_C0; i <= pin_C7; i++) {
digitalWrite(i, high);
Delay_Ms(50);
}
for (int i = pin_C7; i >= pin_C0; i--) {
digitalWrite(i, low);
Delay_Ms(50);
}
Delay_Ms(250);
count++;
}
}
TARGET:=GPIO
all : flash
PREFIX:=riscv64-unknown-elf
GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
EVT:=../../ch32v003evt
MINICHLINK:=../../minichlink
CH32V003FUN:=../../ch32v003fun
CFLAGS:= \
-g -Os -flto -ffunction-sections \
-static-libgcc \
-march=rv32ec \
-mabi=ilp32e \
-I/usr/include/newlib \
-I$(CH32V003FUN) \
-nostdlib \
-I. -DTINYVECTOR -Wall
LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections -L../../misc -lgcc
SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
$(TARGET).elf : $(SYSTEM_C) $(TARGET).c wiring_digital.c
$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
$(TARGET).bin : $(TARGET).elf
$(PREFIX)-size $^
$(PREFIX)-objdump -S $^ > $(TARGET).lst
$(PREFIX)-objdump -t $^ > $(TARGET).map
$(PREFIX)-objcopy -O binary $< $(TARGET).bin
$(PREFIX)-objcopy -O ihex $< $(TARGET).hex
flash : $(TARGET).bin
$(MINICHLINK)/minichlink -w $< flash -b
clean :
rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
# GPIO Libaray
On the shoulders of the Blink example, this Arduino-like GPIO library stands.
All pins are adressable as outputs, inputs, with pull-up, etc.
The pins are in an enum, so you can call them by their name and iterate over them.
It's your responsibility to not blow up a pin.
Only use one pin for one thing and you should be fine.
# GPIO Example
Connect LED + 1k resistor to each pin (C0 to C7 and D4) and GND.
Marvel at the colorful glory.
https://user-images.githubusercontent.com/104343143/231585338-725f1197-dfa0-484d-8707-f0824af80b7e.mp4
//#include <stdio.h>
#include "wiring_digital.h"
#include <stdint.h>
enum GPIOports getPort (enum GPIOpins pin) {
if (pin <= pin_A2) {
return port_A;
}
else if (pin <= pin_C7) {
return port_C;
}
else if (pin <= pin_D7) {
return port_D;
}
return port_none;
}
void enablePort(enum GPIOports port) {
// Enable GPIOs
switch (port) {
case port_A:
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA;
break;
case port_C:
RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
break;
case port_D:
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
break;
case port_none:
break;
}
}
void pinMode(enum GPIOpins pin, enum GPIOpinMode mode) {
GPIO_TypeDef * GPIOx;
uint16_t PinOffset = 4;
if (pin <= pin_A2) {
GPIOx = GPIOA;
PinOffset *= pin;
}
else if (pin <= pin_C7) {
GPIOx = GPIOC;
PinOffset *= (pin - 2);
}
else if (pin <= pin_D7) {
GPIOx = GPIOD;
PinOffset *= (pin - 10);
}
else {
return;
}
GPIOx->CFGLR &= ~(0b1111<<PinOffset); // zero the 4 configuration bits
uint8_t target_pin_state = pinState_nochange; // by default, pin shall retain its state
uint8_t modeMask = 0; // configuration mask
switch (mode) {
case pinMode_I_floating:
modeMask = GPIO_CNF_IN_FLOATING;
break;
case pinMode_I_pullUp:
modeMask = GPIO_CNF_IN_PUPD;
target_pin_state = pinState_high;
break;
case pinMode_I_pullDown:
modeMask = GPIO_CNF_IN_PUPD;
target_pin_state = pinState_low;
break;
case pinMode_I_analog:
modeMask = GPIO_CNF_IN_ANALOG;
break;
case pinMode_O_pushPull:
modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP;
break;
case pinMode_O_openDrain:
modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD;
break;
case pinMode_O_pushPullMux:
modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF;
break;
case pinMode_O_openDrainMux:
modeMask = GPIO_Speed_10MHz | GPIO_CNF_OUT_OD_AF;
break;
}
// wirte mask to CFGR
GPIOx->CFGLR |= modeMask<<PinOffset;
// set pin state
if (target_pin_state > pinState_nochange) {
digitalWrite(pin, target_pin_state - 1);
}
}
void digitalWrite(enum GPIOpins pin, uint8_t value) {
// no checks given whether pin is currently being toggled by timer! your output trannys are in your hands! beware the magic smoke!
GPIO_TypeDef * GPIOx;
uint16_t PinOffset = 0;
if (pin <= pin_A2) {
GPIOx = GPIOA;
PinOffset = pin;
}
else if (pin <= pin_C7) {
GPIOx = GPIOC;
PinOffset = (pin - 2);
}
else if (pin <= pin_D7) {
GPIOx = GPIOD;
PinOffset = (pin - 10);
}
else {
return;
}
if (value) {
GPIOx-> BSHR |= 1 << PinOffset;
}
else {
GPIOx-> BSHR |= 1 << (16 + PinOffset);
}
}
uint8_t digitalRead(uint8_t pin) {
GPIO_TypeDef * GPIOx;
uint16_t PinOffset = 0;
if (pin <= pin_A2) {
GPIOx = GPIOA;
PinOffset = pin;
}
else if (pin <= pin_C7) {
GPIOx = GPIOC;
PinOffset = (pin - 2);
}
else if (pin <= pin_D7) {
GPIOx = GPIOD;
PinOffset = (pin - 10);
}
else {
return 0;
}
int8_t result = (GPIOx->INDR >> PinOffset) & 1;
return result;
}
#ifndef WIRING_DIGITAL_H
#define WIRING_DIGITAL_H
#include "../../ch32v003fun/ch32v003fun.h"
// Define the pins that will be used for GPIO
#define MY_GPIO_PIN_1 1
#define MY_GPIO_PIN_2 2
// Add more pins as needed
enum lowhigh {
low,
high,
};
enum GPIOports{
port_A,
port_C,
port_D,
port_none,
};
enum GPIOpins{
pin_A1,
pin_A2,
pin_C0,
pin_C1,
pin_C2,
pin_C3,
pin_C4,
pin_C5,
pin_C6,
pin_C7,
pin_D0,
pin_D1,
pin_D2,
pin_D3,
pin_D4,
pin_D5,
pin_D6,
pin_D7,
pin_none,
};
enum GPIOpinMode {
pinMode_I_floating,
pinMode_I_pullUp, //pull-mode + ODR(1)
pinMode_I_pullDown, //pull-mode + ODR(0)
pinMode_I_analog,
pinMode_O_pushPull,
pinMode_O_openDrain,
pinMode_O_pushPullMux,
pinMode_O_openDrainMux,
};
enum GPIOpinState {
pinState_nochange,
pinState_low,
pinState_high,
};
enum GPIOports getPort (enum GPIOpins pin);
void enablePort(enum GPIOports port);
void pinMode(enum GPIOpins pin, enum GPIOpinMode mode);
void digitalWrite(enum GPIOpins pin, uint8_t value);
uint8_t digitalRead(uint8_t pin);
#endif // WIRING_DIGITAL_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment