TheLegace

STM32F4

Feb 12th, 2013
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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/scb.h>
  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.  
  232. void pwm1_setup(void){
  233.    
  234.    
  235.     timer_reset(TIM1);
  236.     timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
  237.  
  238.     timer_set_prescaler(TIM1, 0);    
  239.     timer_enable_preload(TIM1);
  240.     timer_continuous_mode(TIM1);
  241.     timer_set_period(TIM1, 168000000 / 32000);
  242.    
  243.     timer_disable_oc_output(TIM1, TIM_OC1);
  244.    
  245.     timer_disable_oc_output(TIM1, TIM_OC1N);
  246.     timer_disable_oc_clear(TIM1, TIM_OC1N);
  247.     timer_enable_oc_preload(TIM1, TIM_OC1N);
  248.    
  249.     timer_disable_oc_clear(TIM1, TIM_OC1);
  250.     timer_enable_oc_preload(TIM1, TIM_OC1);
  251.    
  252.     timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1);
  253.     timer_set_oc_value(TIM1, TIM_OC1, 1200);
  254.    
  255.     // Applies to CH1
  256.     //timer_set_oc_mode(TIM1, TIM_OC1N, TIM_OCM_PWM2);
  257.      
  258.     timer_enable_oc_output(TIM1, TIM_OC1);
  259.     timer_enable_oc_output(TIM1, TIM_OC1N);
  260.    
  261.     timer_enable_preload(TIM1);
  262.     timer_disable_preload_complementry_enable_bits(TIM1);
  263.     timer_enable_break_main_output(TIM1);
  264.    
  265.     timer_enable_counter(TIM1);
  266.     timer_enable_irq(TIM1, TIM_DIER_CC1IE);
  267.     nvic_enable_irq(NVIC_TIM1_CC_IRQ);    
  268. }
  269.  
  270. void tim4_isr(){
  271.     timer_clear_flag(TIM4, TIM_SR_UIF);
  272.     gpio_clear(GPIOD, GPIO12|GPIO13|GPIO14);
  273.     //~ while (usbd_ep_write_packet(usbd_dev, 0x82, "2", 1) == 0)
  274.                 //~ ;
  275. }
  276.  
  277. void tim1_cc_isr(){
  278.     timer_clear_flag(TIM1, TIM_SR_CC1IF);
  279.     gpio_toggle(GPIOD, GPIO14);
  280. }
  281.  
  282. void startup(){
  283.     nvic_enable_irq(NVIC_TIM4_IRQ);
  284.     //~ timer_reset(TIM4);
  285.     timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
  286.     timer_set_prescaler(TIM4, 16800); //168000000/16800 = 10000 ticks/s
  287.     timer_set_period(TIM4,10000); // 10000/10000 = 1s
  288.     timer_one_shot_mode(TIM4);
  289.     //~ timer_continuous_mode(TIM4);
  290.    
  291.     //~ timer_enable_preload(TIM4);
  292.     //~ timer_disable_preload(TIM4);
  293.     gpio_set(GPIOD, GPIO12|GPIO13|GPIO14);
  294.     timer_enable_irq(TIM4, TIM_DIER_UIE);
  295.     timer_enable_counter(TIM4);
  296.        
  297. }
  298.  
  299.  
  300. char parse_bytes(u8 *command){
  301.     switch(command[0]){
  302.         case SET_SPEED:
  303.             switch(command[1]){
  304.                 case ID_FL:
  305.                     gpio_toggle(GPIOD, GPIO13);
  306.                     while (usbd_ep_write_packet(usbd_dev, 0x82, "SPEED", 5) == 0)
  307.                         ;
  308.                     break;
  309.             }
  310.         case START_UP:
  311.             while (usbd_ep_write_packet(usbd_dev, 0x82, "1", 1) == 0)
  312.                 ;
  313.             gpio_clear(GPIOD, GPIO12|GPIO13|GPIO14);
  314.             startup();
  315.             break;
  316.         case GET_SPEED:
  317.             break;
  318.     }
  319.     return 0;
  320. }
  321.  
  322. int main(void)
  323. {
  324.     rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]);
  325.  
  326.     rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM4EN);
  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.     u32 len;
  350.     ring_init(&rx_ring, rx_buffer, RX_BUFFER_SIZE);
  351.     pwm1_setup();
  352.     while (1){
  353.         usbd_poll(usbd_dev);
  354.        
  355.         if (rx_ring.count >= 4){
  356.             len = ring_read(&rx_ring, command, 4);
  357.             if(len){
  358.                 parse_bytes(command);
  359.             }          
  360.         }
  361.     }
  362. }
Advertisement
Add Comment
Please, Sign In to add comment