View difference between Paste ID: YJdM4u9A and 1WkDQpCj
SHOW: | | - or go back to the newest paste.
1
/*
2
 * This file is part of the libopencm3 project.
3
 *
4
 * Copyright (C) 2010 Gareth McMullin <[email protected]>
5
 *
6
 * This library is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include <stdlib.h>
21
#include <libopencm3/stm32/f4/rcc.h>
22
#include <libopencm3/stm32/f4/gpio.h>
23
#include <libopencm3/stm32/f4/timer.h>
24
#include <libopencm3/stm32/f4/nvic.h>
25
#include <libopencm3/usb/usbd.h>
26
#include <libopencm3/usb/cdc.h>
27-
#include <libopencm3/cm3/nvic.h>
27+
28
#include "ring.h"
29
#include "fourbyte.h"
30
#include "timer.h"
31
32
#define RX_BUFFER_SIZE    128
33
static struct ring rx_ring;
34
static u8 rx_buffer[RX_BUFFER_SIZE];
35
static usbd_device *usbd_dev;
36
//static bool start;
37
38
static const struct usb_device_descriptor dev = {
39
	.bLength = USB_DT_DEVICE_SIZE,
40
	.bDescriptorType = USB_DT_DEVICE,
41
	.bcdUSB = 0x0200,
42
	.bDeviceClass = USB_CLASS_CDC,
43
	.bDeviceSubClass = 0,
44
	.bDeviceProtocol = 0,
45
	.bMaxPacketSize0 = 64,
46
	.idVendor = 0x0483,
47
	.idProduct = 0x5740,
48
	.bcdDevice = 0x0200,
49
	.iManufacturer = 1,
50
	.iProduct = 2,
51
	.iSerialNumber = 3,
52
	.bNumConfigurations = 1,
53
};
54
55
/*
56
 * This notification endpoint isn't implemented. According to CDC spec it's
57
 * optional, but its absence causes a NULL pointer dereference in the
58
 * Linux cdc_acm driver.
59
 */
60
static const struct usb_endpoint_descriptor comm_endp[] = {{
61
	.bLength = USB_DT_ENDPOINT_SIZE,
62
	.bDescriptorType = USB_DT_ENDPOINT,
63
	.bEndpointAddress = 0x83,
64
	.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
65
	.wMaxPacketSize = 16,
66
	.bInterval = 255,
67
}};
68
69
static const struct usb_endpoint_descriptor data_endp[] = {{
70
	.bLength = USB_DT_ENDPOINT_SIZE,
71
	.bDescriptorType = USB_DT_ENDPOINT,
72
	.bEndpointAddress = 0x01,
73
	.bmAttributes = USB_ENDPOINT_ATTR_BULK,
74
	.wMaxPacketSize = 64,
75
	.bInterval = 1,
76
}, {
77
	.bLength = USB_DT_ENDPOINT_SIZE,
78
	.bDescriptorType = USB_DT_ENDPOINT,
79
	.bEndpointAddress = 0x82,
80
	.bmAttributes = USB_ENDPOINT_ATTR_BULK,
81
	.wMaxPacketSize = 64,
82
	.bInterval = 1,
83
}};
84
85
static const struct {
86
	struct usb_cdc_header_descriptor header;
87
	struct usb_cdc_call_management_descriptor call_mgmt;
88
	struct usb_cdc_acm_descriptor acm;
89
	struct usb_cdc_union_descriptor cdc_union;
90
} __attribute__((packed)) cdcacm_functional_descriptors = {
91
	.header = {
92
		.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
93
		.bDescriptorType = CS_INTERFACE,
94
		.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
95
		.bcdCDC = 0x0110,
96
	},
97
	.call_mgmt = {
98
		.bFunctionLength =
99
			sizeof(struct usb_cdc_call_management_descriptor),
100
		.bDescriptorType = CS_INTERFACE,
101
		.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
102
		.bmCapabilities = 0,
103
		.bDataInterface = 1,
104
	},
105
	.acm = {
106
		.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
107
		.bDescriptorType = CS_INTERFACE,
108
		.bDescriptorSubtype = USB_CDC_TYPE_ACM,
109
		.bmCapabilities = 0,
110
	},
111
	.cdc_union = {
112
		.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
113
		.bDescriptorType = CS_INTERFACE,
114
		.bDescriptorSubtype = USB_CDC_TYPE_UNION,
115
		.bControlInterface = 0,
116
		.bSubordinateInterface0 = 1,
117
	 }
118
};
119
120
static const struct usb_interface_descriptor comm_iface[] = {{
121
	.bLength = USB_DT_INTERFACE_SIZE,
122
	.bDescriptorType = USB_DT_INTERFACE,
123
	.bInterfaceNumber = 0,
124
	.bAlternateSetting = 0,
125
	.bNumEndpoints = 1,
126
	.bInterfaceClass = USB_CLASS_CDC,
127
	.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
128
	.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
129
	.iInterface = 0,
130
131
	.endpoint = comm_endp,
132
133
	.extra = &cdcacm_functional_descriptors,
134
	.extralen = sizeof(cdcacm_functional_descriptors)
135
}};
136
137
static const struct usb_interface_descriptor data_iface[] = {{
138
	.bLength = USB_DT_INTERFACE_SIZE,
139
	.bDescriptorType = USB_DT_INTERFACE,
140
	.bInterfaceNumber = 1,
141
	.bAlternateSetting = 0,
142
	.bNumEndpoints = 2,
143
	.bInterfaceClass = USB_CLASS_DATA,
144
	.bInterfaceSubClass = 0,
145
	.bInterfaceProtocol = 0,
146
	.iInterface = 0,
147
148
	.endpoint = data_endp,
149
}};
150
151
static const struct usb_interface ifaces[] = {{
152
	.num_altsetting = 1,
153
	.altsetting = comm_iface,
154
}, {
155
	.num_altsetting = 1,
156
	.altsetting = data_iface,
157
}};
158
159
static const struct usb_config_descriptor config = {
160
	.bLength = USB_DT_CONFIGURATION_SIZE,
161
	.bDescriptorType = USB_DT_CONFIGURATION,
162
	.wTotalLength = 0,
163
	.bNumInterfaces = 2,
164
	.bConfigurationValue = 1,
165
	.iConfiguration = 0,
166
	.bmAttributes = 0x80,
167
	.bMaxPower = 0x32,
168
169
	.interface = ifaces,
170
};
171
172
static const char *usb_strings[] = {
173
	"Black Sphere Technologies",
174
	"CDC-ACM Demo",
175
	"DEMO",
176
};
177
178
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf,
179
		u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
180
{
181
	(void)complete;
182
	(void)buf;
183
	(void)usbd_dev;
184
185
	switch (req->bRequest) {
186
	case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
187
		/*
188
		 * This Linux cdc_acm driver requires this to be implemented
189
		 * even though it's optional in the CDC spec, and we don't
190
		 * advertise it in the ACM functional descriptor.
191
		 */
192
		return 1;
193
		}
194
	case USB_CDC_REQ_SET_LINE_CODING:
195
		if (*len < sizeof(struct usb_cdc_line_coding))
196
			return 0;
197
198
		return 1;
199
	}
200
	return 0;
201
}
202
203
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep)
204
{
205
	(void)ep;
206
207
	char buf[64];
208
	int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
209
210
	if (len) {
211
		ring_write(&rx_ring, (u8 *) buf, (u32) len);
212
	}
213
214
	gpio_toggle(GPIOC, GPIO5);
215
}
216
217
static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue)
218
{
219
	(void)wValue;
220
221
	usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
222
	usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
223
	usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
224
225
	usbd_register_control_callback(
226
				usbd_dev,
227
				USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
228
				USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
229
				cdcacm_control_request);
230
}
231-
void nvic_setup(void)
231+
232
void pwm1_setup(void){
233-
        /* Without this the timer interrupt routine will never be called. */
233+
234-
        nvic_enable_irq(NVIC_TIM2_IRQ);
234+
235-
        nvic_set_priority(NVIC_TIM2_IRQ, 1);
235+
    timer_reset(TIM1);
236
    timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
237
238-
void tim2_init(void){
238+
    timer_set_prescaler(TIM1, 0);    
239-
                rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN);     
239+
    timer_enable_preload(TIM1);
240-
        /* Set timer start value. */
240+
    timer_continuous_mode(TIM1);
241-
        TIM_CNT(TIM2) = 1;
241+
    timer_set_period(TIM1, 168000000 / 32000);
242
    
243-
        /* Set timer prescaler. 120MHz/120000 => 1000 counts per second. */
243+
    timer_disable_oc_output(TIM1, TIM_OC1);
244-
        TIM_PSC(TIM2) = 120000;
244+
245
    timer_disable_oc_output(TIM1, TIM_OC1N);
246-
        /* End timer value. If this is reached an interrupt is generated. */
246+
	timer_disable_oc_clear(TIM1, TIM_OC1N);
247-
        TIM_ARR(TIM2) = 1000;
247+
    timer_enable_oc_preload(TIM1, TIM_OC1N);
248
    
249-
        /* Update interrupt enable. */
249+
	timer_disable_oc_clear(TIM1, TIM_OC1);
250-
        TIM_DIER(TIM2) |= TIM_DIER_UIE;
250+
    timer_enable_oc_preload(TIM1, TIM_OC1);
251
    
252-
        /* Start timer. */
252+
    timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1);
253-
        TIM_CR1(TIM2) |= TIM_CR1_CEN;
253+
    timer_set_oc_value(TIM1, TIM_OC1, 1200);
254
    
255
    // Applies to CH1
256-
void tim2_isr(void)
256+
    //timer_set_oc_mode(TIM1, TIM_OC1N, TIM_OCM_PWM2);
257
     
258-
        //gpio_toggle(GPIOB, GPIO6);   /* LED2 on/off. */
258+
    timer_enable_oc_output(TIM1, TIM_OC1);
259-
        TIM_SR(TIM2) &= ~TIM_SR_UIF; /* Clear interrrupt flag. */
259+
    timer_enable_oc_output(TIM1, TIM_OC1N);
260-
        ring_init(&rx_ring, rx_buffer, RX_BUFFER_SIZE);    
260+
261
    timer_enable_preload(TIM1);
262
    timer_disable_preload_complementry_enable_bits(TIM1);
263-
void setup_periodic_timer(uint32_t timer, unsigned int freq_in_hz)
263+
    timer_enable_break_main_output(TIM1);
264
    
265-
    unsigned int prescaler = 1;
265+
    timer_enable_counter(TIM1);
266-
    while (rcc_ppre1_frequency / prescaler / freq_in_hz > 0xffff)
266+
    timer_enable_irq(TIM1, TIM_DIER_CC1IE);
267-
        prescaler *= 2;
267+
    nvic_enable_irq(NVIC_TIM1_CC_IRQ);    
268-
    timer_reset(timer);
268+
269-
    timer_set_prescaler(timer, prescaler-1);
269+
270-
    timer_set_period(timer, rcc_ppre1_frequency / prescaler / freq_in_hz);
270+
271-
    timer_direction_down(timer);
271+
	timer_clear_flag(TIM4, TIM_SR_UIF);
272-
    timer_enable_preload(timer);
272+
	gpio_clear(GPIOD, GPIO12|GPIO13|GPIO14);
273
	//~ while (usbd_ep_write_packet(usbd_dev, 0x82, "2", 1) == 0)
274
				//~ ;
275-
void gpio_setup(void){
275+
276
277-
	/* Enable GPIOD clock. */
277+
void tim1_cc_isr(){
278-
	rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN);
278+
	timer_clear_flag(TIM1, TIM_SR_CC1IF);
279-
	/* Set GPIO12 (in GPIO port D) to 'output push-pull'. */
279+
	gpio_toggle(GPIOD, GPIO14);
280-
	gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO13);
280+
281
282
void startup(){
283
	nvic_enable_irq(NVIC_TIM4_IRQ);
284-
void tim_setup(void){
284+
    //~ timer_reset(TIM4);
285
    timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
286-
	gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12);
286+
    timer_set_prescaler(TIM4, 16800); //168000000/16800 = 10000 ticks/s
287-
	gpio_set_af(GPIOD, GPIO_AF2, GPIO12);
287+
    timer_set_period(TIM4,10000); // 10000/10000 = 1s
288-
	//~ timer_reset(TIM4);
288+
    timer_one_shot_mode(TIM4);
289-
	//~ timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
289+
    //~ timer_continuous_mode(TIM4);
290-
	//~ timer_set_prescaler(TIM4, 0);
290+
291-
	//~ timer_set_repetition_counter(TIM4, 0);
291+
    //~ timer_enable_preload(TIM4);
292-
	//~ timer_enable_preload(TIM4);
292+
    //~ timer_disable_preload(TIM4);
293-
	//~ timer_continuous_mode(TIM4);
293+
    gpio_set(GPIOD, GPIO12|GPIO13|GPIO14);
294-
	//~ timer_set_period(TIM4, 168000000 / 32000);
294+
    timer_enable_irq(TIM4, TIM_DIER_UIE);
295-
	//~ timer_disable_oc_output(TIM4, TIM_OC1);
295+
296-
	//~ timer_disable_oc_clear(TIM4, TIM_OC1);
296+
        
297-
	//~ timer_enable_oc_preload(TIM4, TIM_OC1);
297+
298-
	//~ timer_set_oc_mode(TIM4, TIM_OC1, TIM_OCM_PWM1);
298+
299-
	//~ timer_set_oc_value(TIM4, TIM_OC1, 5260);
299+
300-
	//~ timer_enable_oc_output(TIM4, TIM_OC1);
300+
301-
	//~ timer_enable_preload(TIM4);
301+
302-
	//~ timer_enable_counter(TIM4);
302+
303
			switch(command[1]){ 
304
				case ID_FL:
305-
    nvic_enable_irq(NVIC_TIM4_IRQ);
305+
306-
    timer_reset(TIM4);
306+
307
						;
308-
    timer_set_prescaler(TIM4, 0);
308+
309-
    timer_enable_preload(TIM4); 
309+
310-
    timer_continuous_mode(TIM4);
310+
		case START_UP:
311-
    timer_set_period(TIM4, 168000000 / 32000);
311+
			while (usbd_ep_write_packet(usbd_dev, 0x82, "1", 1) == 0)
312
				;
313-
    timer_disable_oc_output(TIM4, TIM_OC1);
313+
			gpio_clear(GPIOD, GPIO12|GPIO13|GPIO14);
314-
	timer_disable_oc_clear(TIM4, TIM_OC1);
314+
			startup();
315-
    timer_enable_oc_preload(TIM4, TIM_OC1);
315+
316-
    timer_set_oc_mode(TIM4, TIM_OC1, TIM_OCM_PWM1);
316+
317-
    timer_set_oc_value(TIM4, TIM_OC1, 1000);
317+
318
	}
319-
    timer_enable_oc_output(TIM4, TIM_OC1);
319+
320-
    timer_enable_preload(TIM4);
320+
321-
    timer_enable_irq(TIM4, TIM_DIER_CC4IE);
321+
322
int main(void)
323
{
324
	rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]);
325
326-
	timer_clear_flag(TIM4, 0xffffffff);
326+
327
	rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
328
	rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN);	
329
	
330
	rcc_peripheral_enable_clock(&RCC_AHB1ENR,
331
					RCC_AHB1ENR_IOPAEN | 
332
					RCC_AHB1ENR_IOPBEN |
333
					RCC_AHB1ENR_IOPDEN |
334
					RCC_AHB1ENR_IOPEEN);
335
	
336
	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
337
			GPIO9 | GPIO11 | GPIO12);
338
	gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12);
339
	
340
	gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12|GPIO13|GPIO14);
341
	
342
	gpio_mode_setup(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8|GPIO9);
343
	gpio_set_af(GPIOE, GPIO_AF1, GPIO8|GPIO9);
344
345
	usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings, 3);
346
	usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
347
	
348
	u8 command[4];
349-
	rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]);
349+
350
    ring_init(&rx_ring, rx_buffer, RX_BUFFER_SIZE);
351-
	rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN);
351+
	pwm1_setup();
352-
	rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN);
352+
353-
	rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN);
353+
354
		
355
		if (rx_ring.count >= 4){
356-
	gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12|GPIO13);
356+
357-
	gpio_set_af(GPIOD, GPIO_AF2, GPIO12|GPIO13);
357+
358
				parse_bytes(command);
359
			}			
360
		}
361
	}
362
}