summaryrefslogtreecommitdiff
path: root/main.cpp
blob: baad03876fead71cb044fb35005e7a2ba0ba0abc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "stm32.h"
#include "rcc.h"
#include "interrupt.h"
#include "thread.h"
#include "time.h"

#include "pin.h"

#include "usb.h"

static Pin& led_green = PD12;
static Pin& led_yellow = PD13;
static Pin& led_red = PD14;
static Pin& led_blue = PD15;

static Pin& usb_dm = PA11;
static Pin& usb_dp = PA12;
static Pin& usb_vbus = PA9;

template<>
void interrupt<(Interrupt::IRQ)67>() {
	led_blue.toggle();
	led_red.toggle();

	if(OTG_FS.reg.GINTSTS & (1 << 12)) {
		led_yellow.toggle();
		OTG_FS.dev_oep_reg[0].DOEPCTL = (1 << 27);
		OTG_FS.dev_reg.DAINTMSK = (1 << 16) | 1;
		OTG_FS.dev_reg.DOEPMSK = (1 << 3) | 1;
		OTG_FS.dev_reg.DIEPEMPMSK = (1 << 3) | 1;
		OTG_FS.reg.GRXFSIZ = 256;
		OTG_FS.dev_oep_reg[0].DOEPTSIZ = (3 << 29);
	}
	
	OTG_FS.reg.GINTSTS = 0xffffffff;
}

int main() {
	// Initialize system timer.
	STK.LOAD = 168000000 / 8 / 1000; // 1000 Hz.
	STK.CTRL = 0x03;
	
	RCC.enable(RCC.GPIOA);
	RCC.enable(RCC.GPIOB);
	RCC.enable(RCC.GPIOD);
	
	led_green.set_mode(Pin::Output);
	led_yellow.set_mode(Pin::Output);
	led_red.set_mode(Pin::Output);
	led_blue.set_mode(Pin::Output);
	
	led_red.on();
	led_blue.off();
	
	usb_vbus.set_mode(Pin::AF);
	usb_vbus.set_pull(Pin::PullNone);
	usb_vbus.set_af(10);
	usb_dm.set_mode(Pin::AF);
	usb_dm.set_pull(Pin::PullNone);
	usb_dm.set_af(10);
	usb_dp.set_mode(Pin::AF);
	usb_dp.set_pull(Pin::PullNone);
	usb_dp.set_af(10);
	
	RCC.enable(RCC.OTGFS);
	Interrupt::enable((Interrupt::IRQ)67);
	
	OTG_FS.reg.GAHBCFG = 1;
	
	// USB configuration
	OTG_FS.reg.GUSBCFG = (1 << 30) | (0xf << 10) | (0 << 9) | (0 << 8);
	//                   FDMOD       TRDT          HNPCAP     SRPCAP

	// interrupt mask
	OTG_FS.reg.GINTMSK = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 3) | (1 << 2) | (1 << 1);
	//                   ENUMDNEM    USBRST      USBSUSPM    ESUSPM      SOFM       OTGINT     MMISM

	// device configuration
	OTG_FS.dev_reg.DCFG = (1 << 2) | 3;
	//                    NZLSOHSK   DSPD

	// core configuration
	OTG_FS.reg.GCCFG = (1 << 19);
	//                 VBUSBSEN
	
	while(1) {
		led_green.toggle();
		Time::sleep(100);
	}
}