From 36adeae65a1249a2ba7c871f35741b0540117b66 Mon Sep 17 00:00:00 2001 From: eddyem Date: Thu, 24 Mar 2016 11:44:11 +0300 Subject: [PATCH] added canon lens --- canon_lens/Makefile | 133 ++++++++++++++ canon_lens/README | 11 ++ canon_lens/canon_lens.bin | Bin 0 -> 7716 bytes canon_lens/cdcacm.c | 324 +++++++++++++++++++++++++++++++++++ canon_lens/cdcacm.h | 58 +++++++ canon_lens/hardware_ini.c | 68 ++++++++ canon_lens/hardware_ini.h | 58 +++++++ canon_lens/ld/devices.data | 9 + canon_lens/ld/stm32f103x4.ld | 31 ++++ canon_lens/ld/stm32f103x6.ld | 31 ++++ canon_lens/ld/stm32f103x8.ld | 31 ++++ canon_lens/ld/stm32f103xB.ld | 31 ++++ canon_lens/ld/stm32f103xC.ld | 31 ++++ canon_lens/ld/stm32f103xD.ld | 31 ++++ canon_lens/ld/stm32f103xE.ld | 31 ++++ canon_lens/ld/stm32f103xF.ld | 31 ++++ canon_lens/ld/stm32f103xG.ld | 31 ++++ canon_lens/main.c | 88 ++++++++++ canon_lens/main.h | 53 ++++++ canon_lens/spi.c | 78 +++++++++ canon_lens/spi.h | 31 ++++ canon_lens/sync.c | 93 ++++++++++ canon_lens/sync.h | 53 ++++++ canon_lens/user_proto.c | 250 +++++++++++++++++++++++++++ canon_lens/user_proto.h | 47 +++++ 25 files changed, 1633 insertions(+) create mode 100644 canon_lens/Makefile create mode 100644 canon_lens/README create mode 100755 canon_lens/canon_lens.bin create mode 100644 canon_lens/cdcacm.c create mode 100644 canon_lens/cdcacm.h create mode 100644 canon_lens/hardware_ini.c create mode 100644 canon_lens/hardware_ini.h create mode 100644 canon_lens/ld/devices.data create mode 100644 canon_lens/ld/stm32f103x4.ld create mode 100644 canon_lens/ld/stm32f103x6.ld create mode 100644 canon_lens/ld/stm32f103x8.ld create mode 100644 canon_lens/ld/stm32f103xB.ld create mode 100644 canon_lens/ld/stm32f103xC.ld create mode 100644 canon_lens/ld/stm32f103xD.ld create mode 100644 canon_lens/ld/stm32f103xE.ld create mode 100644 canon_lens/ld/stm32f103xF.ld create mode 100644 canon_lens/ld/stm32f103xG.ld create mode 100644 canon_lens/main.c create mode 100644 canon_lens/main.h create mode 100644 canon_lens/spi.c create mode 100644 canon_lens/spi.h create mode 100644 canon_lens/sync.c create mode 100644 canon_lens/sync.h create mode 100644 canon_lens/user_proto.c create mode 100644 canon_lens/user_proto.h diff --git a/canon_lens/Makefile b/canon_lens/Makefile new file mode 100644 index 0000000..aa0a5d6 --- /dev/null +++ b/canon_lens/Makefile @@ -0,0 +1,133 @@ +BINARY = canon_lens +BOOTPORT ?= /dev/ttyUSB0 +BOOTSPEED ?= 115200 +# change this linking script depending on particular MCU model, +# for example, if you have STM32F103VBT6, you should write: +LDSCRIPT = ld/stm32f103x8.ld +LIBNAME = opencm3_stm32f1 +DEFS = -DSTM32F1 -DEBUG + +OBJDIR = mk +INDEPENDENT_HEADERS= + +FP_FLAGS ?= -msoft-float +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd + +############################################################################### +# Executables +PREFIX ?= arm-none-eabi + +RM := rm -f +RMDIR := rmdir +CC := $(PREFIX)-gcc +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +STFLASH = $(shell which st-flash) +STBOOT = $(shell which stm32flash) + +############################################################################### +# Source files +LDSCRIPT ?= $(BINARY).ld +SRC = $(wildcard *.c) +OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) + +ifeq ($(strip $(OPENCM3_DIR)),) +OPENCM3_DIR := /usr/local/arm-none-eabi +$(info Using $(OPENCM3_DIR) path to library) +endif + +INCLUDE_DIR = $(OPENCM3_DIR)/include +LIB_DIR = $(OPENCM3_DIR)/lib +SCRIPT_DIR = $(OPENCM3_DIR)/scripts + +############################################################################### +# C flags +CFLAGS += -Os -g +CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration +CFLAGS += -Wredundant-decls +# -Wmissing-prototypes -Wstrict-prototypes +CFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C & C++ preprocessor common flags +CPPFLAGS += -MD +CPPFLAGS += -Wall -Werror +CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) + +############################################################################### +# Linker flags +LDFLAGS += --static -nostartfiles +LDFLAGS += -L$(LIB_DIR) +LDFLAGS += -T$(LDSCRIPT) +LDFLAGS += -Wl,-Map=$(*).map +LDFLAGS += -Wl,--gc-sections + +############################################################################### +# Used libraries +LDLIBS += -l$(LIBNAME) +LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group + +.SUFFIXES: .elf .bin .hex .srec .list .map .images +.SECONDEXPANSION: +.SECONDARY: + +ELF := $(OBJDIR)/$(BINARY).elf +LIST := $(OBJDIR)/$(BINARY).list +BIN := $(BINARY).bin +HEX := $(BINARY).hex + +all: bin + +elf: $(ELF) +bin: $(BIN) +hex: $(HEX) +list: $(LIST) + +$(OBJDIR): + mkdir $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @printf " CC $<\n" + $(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< + +$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS) + @touch $@ + +%.h: ; + +$(BIN): $(ELF) + @printf " OBJCOPY $(BIN)\n" + $(OBJCOPY) -Obinary $(ELF) $(BIN) + +$(HEX): $(ELF) + @printf " OBJCOPY $(HEX)\n" + $(OBJCOPY) -Oihex $(ELF) $(HEX) + +$(LIST): $(ELF) + @printf " OBJDUMP $(LIST)\n" + $(OBJDUMP) -S $(ELF) > $(LIST) + +$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + @printf " LD $(ELF)\n" + $(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF) + +clean: + @printf " CLEAN\n" + $(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map + $(RMDIR) $(OBJDIR) + +flash: $(BIN) + @printf " FLASH $(BIN)\n" + $(STFLASH) write $(BIN) 0x8000000 + +boot: $(BIN) + @printf " LOAD $(BIN) through bootloader\n" + $(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN) + +.PHONY: clean elf hex list flash boot + +#-include $(OBJS:.o=.d) diff --git a/canon_lens/README b/canon_lens/README new file mode 100644 index 0000000..ee5062d --- /dev/null +++ b/canon_lens/README @@ -0,0 +1,11 @@ +Canon lens managing + +Functions: +- change focus +- aquire focus motor position +- change diafragm +- allow to send any commands you want ('\n' terminates list, commands can be in octal, hexadecimal or decimal format separated by any non-digital symbol) + +written for chinese devboard based on STM32F103R8T6 + +Press H for help \ No newline at end of file diff --git a/canon_lens/canon_lens.bin b/canon_lens/canon_lens.bin new file mode 100755 index 0000000000000000000000000000000000000000..25bb8282faeb06c29a617f0cd07b951010642c05 GIT binary patch literal 7716 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 literal 0 HcmV?d00001 diff --git a/canon_lens/cdcacm.c b/canon_lens/cdcacm.c new file mode 100644 index 0000000..62a7a78 --- /dev/null +++ b/canon_lens/cdcacm.c @@ -0,0 +1,324 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * Copyright 2014 Edward V. Emelianov + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include "cdcacm.h" +#include "user_proto.h" +#include "main.h" + +// Buffer for USB Tx +static uint8_t USB_Tx_Buffer[USB_TX_DATA_SIZE]; +static uint8_t USB_Tx_ptr = 0; +// connection flag +uint8_t USB_connected = 0; +static const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = USB_CLASS_CDC, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0x5740, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +uint8_t usbdatabuf[USB_RX_DATA_SIZE]; // buffer for received data +int usbdatalen = 0; // lenght of received data +uint8_t data_rdy = 0; // got full line or buffer is full + +/* + * This notification endpoint isn't implemented. According to CDC spec its + * optional, but its absence causes a NULL pointer dereference in Linux + * cdc_acm driver. + */ +static const struct usb_endpoint_descriptor comm_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x83, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 16, + .bInterval = 255, +}}; + +static const struct usb_endpoint_descriptor data_endp[] = {{ + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}, { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x82, + .bmAttributes = USB_ENDPOINT_ATTR_BULK, + .wMaxPacketSize = 64, + .bInterval = 1, +}}; + +static const struct { + struct usb_cdc_header_descriptor header; + struct usb_cdc_call_management_descriptor call_mgmt; + struct usb_cdc_acm_descriptor acm; + struct usb_cdc_union_descriptor cdc_union; +} __attribute__((packed)) cdcacm_functional_descriptors = { + .header = { + .bFunctionLength = sizeof(struct usb_cdc_header_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_HEADER, + .bcdCDC = 0x0110, + }, + .call_mgmt = { + .bFunctionLength = + sizeof(struct usb_cdc_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_CDC_TYPE_UNION, + .bControlInterface = 0, + .bSubordinateInterface0 = 1, + }, +}; + +static const struct usb_interface_descriptor comm_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, + .iInterface = 0, + + .endpoint = comm_endp, + + .extra = &cdcacm_functional_descriptors, + .extralen = sizeof(cdcacm_functional_descriptors), +}}; + +static const struct usb_interface_descriptor data_iface[] = {{ + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, + + .endpoint = data_endp, +}}; + +static const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = comm_iface, +}, { + .num_altsetting = 1, + .altsetting = data_iface, +}}; + +static const struct usb_config_descriptor config = { + .bLength = USB_DT_CONFIGURATION_SIZE, + .bDescriptorType = USB_DT_CONFIGURATION, + .wTotalLength = 0, + .bNumInterfaces = 2, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0x80, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "Organisation, author", + "device", + "version", +}; + +// default line coding: B115200, 1stop, 8bits, parity none +struct usb_cdc_line_coding linecoding = { + .dwDTERate = 115200, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, +}; + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; + +/** + * This function runs every time it gets a request for control parameters get/set + * parameter SET_LINE_CODING used to change USART1 parameters: if you want to + * change them, just connect through USB with required parameters + */ +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, + uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)){ + (void)complete; + (void)buf; + (void)usbd_dev; + char local_buf[10]; + struct usb_cdc_line_coding lc; + + switch (req->bRequest) { + case SET_CONTROL_LINE_STATE:{ + if(req->wValue){ // terminal is opened + USB_connected = 1; + }else{ // terminal is closed + USB_connected = 0; + } + /* + * This Linux cdc_acm driver requires this to be implemented + * even though it's optional in the CDC spec, and we don't + * advertise it in the ACM functional descriptor. + */ + struct usb_cdc_notification *notif = (void *)local_buf; + /* We echo signals back to host as notification. */ + notif->bmRequestType = 0xA1; + notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE; + notif->wValue = 0; + notif->wIndex = 0; + notif->wLength = 2; + local_buf[8] = req->wValue & 3; + local_buf[9] = 0; + usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10); + }break; + case SET_LINE_CODING: + if (!len || (*len != sizeof(struct usb_cdc_line_coding))) + return 0; + memcpy((void *)&lc, (void *)*buf, *len); + // Mark & Space parity don't support by hardware, check it + if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){ + return 0; // error + }else{ +// memcpy((void *)&linecoding, (void *)&lc, sizeof(struct usb_cdc_line_coding)); +// UART_setspeed(USART1, &linecoding); + } + break; + case GET_LINE_CODING: // return linecoding buffer + if(len && *len == sizeof(struct usb_cdc_line_coding)) + memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding)); + //usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding)); + break; + default: + return 0; + } + return 1; +} + +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep){ + (void)ep; + int len = usbd_ep_read_packet(usbd_dev, 0x01, usbdatabuf + usbdatalen, USB_RX_DATA_SIZE - usbdatalen); + if(len < 1) return; + int i, ol = usbdatalen; + usbdatalen += len; + // echo readed data + for(i = ol; i < usbdatalen; ++i) usb_send(usbdatabuf[i]); + // check for end of input + if(usbdatalen == USB_RX_DATA_SIZE || usbdatabuf[usbdatalen-1] == '\n'){ + ++data_rdy; + } +} + +void empty_buf(){ + data_rdy = 0; + usbdatalen = 0; +} + +static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep){ + (void)ep; + (void)usbd_dev; + usb_send_buffer(); +} + +static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) +{ + (void)wValue; + (void)usbd_dev; + + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, USB_RX_DATA_SIZE, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, USB_TX_DATA_SIZE, cdcacm_data_tx_cb); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + cdcacm_control_request); +} + +static usbd_device *current_usb = NULL; + +usbd_device *USB_init(){ + current_usb = usbd_init(&stm32f103_usb_driver, &dev, &config, + usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + if(!current_usb) return NULL; + usbd_register_set_config_callback(current_usb, cdcacm_set_config); + return current_usb; +} + +mutex_t send_block_mutex = MUTEX_UNLOCKED; +/** + * Put byte into USB buffer to send + * @param byte - a byte to put into a buffer + */ +void usb_send(uint8_t byte){ + mutex_lock(&send_block_mutex); + USB_Tx_Buffer[USB_Tx_ptr++] = byte; + mutex_unlock(&send_block_mutex); + if(USB_Tx_ptr == USB_TX_DATA_SIZE){ // buffer can be overflowed - send it! + usb_send_buffer(); + } +} + +/** + * Send all data in buffer over USB + * this function runs when buffer is full or on SysTick + */ +void usb_send_buffer(){ + if(MUTEX_LOCKED == mutex_trylock(&send_block_mutex)) return; + if(USB_Tx_ptr){ + if(current_usb && USB_connected){ + // usbd_ep_write_packet return 0 if previous packet isn't transmit yet + while(USB_Tx_ptr != usbd_ep_write_packet(current_usb, 0x82, USB_Tx_Buffer, USB_Tx_ptr)); + usbd_poll(current_usb); + } + USB_Tx_ptr = 0; + } + mutex_unlock(&send_block_mutex); +} diff --git a/canon_lens/cdcacm.h b/canon_lens/cdcacm.h new file mode 100644 index 0000000..76a0914 --- /dev/null +++ b/canon_lens/cdcacm.h @@ -0,0 +1,58 @@ +/* + * ccdcacm.h + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __CCDCACM_H__ +#define __CCDCACM_H__ + +#include + +// commands through EP0 +#define SEND_ENCAPSULATED_COMMAND 0x00 +#define GET_ENCAPSULATED_RESPONSE 0x01 +#define SET_COMM_FEATURE 0x02 +#define GET_COMM_FEATURE 0x03 +#define CLEAR_COMM_FEATURE 0x04 +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 +#define SEND_BREAK 0x23 + +// Size of input/output buffers +#define USB_TX_DATA_SIZE (64) +#define USB_RX_DATA_SIZE (256) + +// USB connection flag +extern uint8_t USB_connected; +extern struct usb_cdc_line_coding linecoding; + +extern uint8_t usbdatabuf[]; +extern int usbdatalen; + +extern uint8_t data_rdy; + +usbd_device *USB_init(); +void usb_send(uint8_t byte); +void usb_send_buffer(); + +void empty_buf(); + +#endif // __CCDCACM_H__ diff --git a/canon_lens/hardware_ini.c b/canon_lens/hardware_ini.c new file mode 100644 index 0000000..0e8734d --- /dev/null +++ b/canon_lens/hardware_ini.c @@ -0,0 +1,68 @@ +/* + * hardware_ini.c - functions for HW initialisation + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + * All hardware-dependent initialisation & definition should be placed here + * and in hardware_ini.h + * + */ + +#include "main.h" +#include "hardware_ini.h" + +/** + * GPIO initialisaion: clocking + pins setup + */ +void GPIO_init(){ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | + RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | + RCC_APB2ENR_IOPEEN); + /* + // Buttons: pull-up input + gpio_set_mode(BTNS_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, + BTN_S2_PIN | BTN_S3_PIN); + // turn on pull-up + gpio_set(BTNS_PORT, BTN_S2_PIN | BTN_S3_PIN); + // LEDS: opendrain output + gpio_set_mode(LEDS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, + LED_D1_PIN | LED_D2_PIN); + // turn off LEDs + gpio_set(LEDS_PORT, LED_D1_PIN | LED_D2_PIN); + */ +/* + // USB_DISC: push-pull + gpio_set_mode(USB_DISC_PORT, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, USB_DISC_PIN); + // USB_POWER: open drain, externall pull down with R7 (22k) + gpio_set_mode(USB_POWER_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_FLOAT, USB_POWER_PIN); +*/ +} + +/* + * SysTick used for system timer with period of 1ms + */ +void SysTick_init(){ + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz + systick_set_reload(8999); // 9000 pulses: 1kHz + systick_interrupt_enable(); + systick_counter_enable(); +} diff --git a/canon_lens/hardware_ini.h b/canon_lens/hardware_ini.h new file mode 100644 index 0000000..5e00745 --- /dev/null +++ b/canon_lens/hardware_ini.h @@ -0,0 +1,58 @@ +/* + * hardware_ini.h + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __HARDWARE_INI_H__ +#define __HARDWARE_INI_H__ + +/* + * Timers: + * SysTick - system time + */ + + +void GPIO_init(); +void SysTick_init(); + +/* + * USB interface + * connect boot1 jumper to gnd, boot0 to gnd; and reconnect boot0 to +3.3 to boot flash + */ +/* +// USB_DICS (disconnect) - PC11 +#define USB_DISC_PIN GPIO11 +#define USB_DISC_PORT GPIOC +// USB_POWER (high level when USB connected to PC) +#define USB_POWER_PIN GPIO10 +#define USB_POWER_PORT GPIOC +// change signal level on USB diconnect pin +#define usb_disc_high() gpio_set(USB_DISC_PORT, USB_DISC_PIN) +#define usb_disc_low() gpio_clear(USB_DISC_PORT, USB_DISC_PIN) +// in case of n-channel FET on 1.5k pull-up change on/off disconnect means low level +// in case of pnp bipolar transistor or p-channel FET on 1.5k pull-up disconnect means high level +#define usb_disconnect() usb_disc_high() +#define usb_connect() usb_disc_low() +*/ +// my simple devboard have no variants for programmed connection/disconnection of USB +#define usb_disconnect() +#define usb_connect() + +#endif // __HARDWARE_INI_H__ diff --git a/canon_lens/ld/devices.data b/canon_lens/ld/devices.data new file mode 100644 index 0000000..7f29538 --- /dev/null +++ b/canon_lens/ld/devices.data @@ -0,0 +1,9 @@ +stm32f103?4* stm32f1 ROM=16K RAM=6K +stm32f103?6* stm32f1 ROM=32K RAM=10K +stm32f103?8* stm32f1 ROM=64K RAM=20K +stm32f103?b* stm32f1 ROM=128K RAM=20K +stm32f103?c* stm32f1 ROM=256K RAM=48K +stm32f103?d* stm32f1 ROM=384K RAM=64K +stm32f103?e* stm32f1 ROM=512K RAM=64K +stm32f103?f* stm32f1 ROM=768K RAM=96K +stm32f103?g* stm32f1 ROM=1024K RAM=96K diff --git a/canon_lens/ld/stm32f103x4.ld b/canon_lens/ld/stm32f103x4.ld new file mode 100644 index 0000000..efed65e --- /dev/null +++ b/canon_lens/ld/stm32f103x4.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103x6.ld b/canon_lens/ld/stm32f103x6.ld new file mode 100644 index 0000000..13f05f9 --- /dev/null +++ b/canon_lens/ld/stm32f103x6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103x8.ld b/canon_lens/ld/stm32f103x8.ld new file mode 100644 index 0000000..2c4640f --- /dev/null +++ b/canon_lens/ld/stm32f103x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xB.ld b/canon_lens/ld/stm32f103xB.ld new file mode 100644 index 0000000..138444d --- /dev/null +++ b/canon_lens/ld/stm32f103xB.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xC.ld b/canon_lens/ld/stm32f103xC.ld new file mode 100644 index 0000000..fda76bf --- /dev/null +++ b/canon_lens/ld/stm32f103xC.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xD.ld b/canon_lens/ld/stm32f103xD.ld new file mode 100644 index 0000000..0f996c2 --- /dev/null +++ b/canon_lens/ld/stm32f103xD.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xE.ld b/canon_lens/ld/stm32f103xE.ld new file mode 100644 index 0000000..b0fcb69 --- /dev/null +++ b/canon_lens/ld/stm32f103xE.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xF.ld b/canon_lens/ld/stm32f103xF.ld new file mode 100644 index 0000000..62d47db --- /dev/null +++ b/canon_lens/ld/stm32f103xF.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/ld/stm32f103xG.ld b/canon_lens/ld/stm32f103xG.ld new file mode 100644 index 0000000..0c0c968 --- /dev/null +++ b/canon_lens/ld/stm32f103xG.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/canon_lens/main.c b/canon_lens/main.c new file mode 100644 index 0000000..b983d45 --- /dev/null +++ b/canon_lens/main.c @@ -0,0 +1,88 @@ +/* + * main.c + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "main.h" +#include "hardware_ini.h" +#include "cdcacm.h" +#include "spi.h" + +volatile uint32_t Timer = 0; // global timer (milliseconds) +usbd_device *usbd_dev; + +int main(){ + uint32_t Old_timer = 0; + + // RCC clocking: 8MHz oscillator -> 72MHz system + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + + GPIO_init(); + + usb_disconnect(); // turn off USB while initializing all + + // USB + usbd_dev = USB_init(); + + // SysTick is a system timer with 1ms period + SysTick_init(); + SPI_init(); + + // wait a little and then turn on USB pullup +// for (i = 0; i < 0x800000; i++) +// __asm__("nop"); + + usb_connect(); // turn on USB + + while(1){ + usbd_poll(usbd_dev); + if(data_rdy){ // there's something in USB buffer + parse_incoming_buf(); + } + if(Timer - Old_timer > 999){ // one-second cycle + Old_timer += 1000; + }else if(Timer < Old_timer){ // Timer overflow + Old_timer = 0; + } + } +} + + +/** + * SysTick interrupt: increment global time & send data buffer through USB + */ +void sys_tick_handler(){ + Timer++; + usbd_poll(usbd_dev); + usb_send_buffer(); +} + +// pause function, delay in ms +void Delay(uint16_t _U_ time){ + uint32_t waitto = Timer + time; + while(Timer < waitto); +} + +/** + * print current time in milliseconds: 4 bytes for ovrvlow + 4 bytes for time + * with ' ' as delimeter + */ +void print_time(){ + print_int(Timer); +} diff --git a/canon_lens/main.h b/canon_lens/main.h new file mode 100644 index 0000000..36090dc --- /dev/null +++ b/canon_lens/main.h @@ -0,0 +1,53 @@ +/* + * main.h + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + + +#pragma once +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include +#include // memcpy +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "sync.h" // mutexes +#include "user_proto.h" + +#define _U_ __attribute__((__unused__)) +#define U8(x) ((uint8_t) x) +#define U16(x) ((uint16_t) x) +#define U32(x) ((uint32_t) x) + +extern volatile uint32_t Timer; // global timer (milliseconds) +void Delay(uint16_t time); + +#endif // __MAIN_H__ + diff --git a/canon_lens/spi.c b/canon_lens/spi.c new file mode 100644 index 0000000..0efd45d --- /dev/null +++ b/canon_lens/spi.c @@ -0,0 +1,78 @@ +/* + * spi.c + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "main.h" +#include "spi.h" + +/* + * Configure SPI ports + */ +/* + * SPI1 remapped: + * SCK - PB3 + * MISO - PB4 + * MOSI - PB5 + * + */ +void SPI_init(){ + // enable AFIO & other clocking + rcc_peripheral_enable_clock(&RCC_APB2ENR, + RCC_APB2ENR_SPI1EN | RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPBEN); + // remap SPI1 (change pins from PA5..7 to PB3..5); also turn off JTAG + gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, AFIO_MAPR_SPI1_REMAP); + // SCK, MOSI - push-pull output + gpio_set_mode(GPIO_BANK_SPI1_RE_SCK, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_SCK); + gpio_set_mode(GPIO_BANK_SPI1_RE_MOSI, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_SPI1_RE_MOSI); + // MISO - opendrain in + gpio_set_mode(GPIO_BANK_SPI1_RE_MISO, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_SPI1_RE_MISO); + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_DIV4); + spi_reset(SPI1); + /* Set up SPI in Master mode with: + * for Canon lens SPI settings are: f~78kHz, CPOL=1, CPHA=1 + * Clock baud rate: 1/256 of peripheral clock frequency (APB2, 72MHz/4 = 18MHz) - ~70kHz + * Clock polarity: CPOL=1, CPHA=1 + * Data frame format: 8-bit + * Frame format: MSB First + */ + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_256, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + //nvic_enable_irq(NVIC_SPI1_IRQ); // enable SPI interrupt + spi_enable(SPI1); +} + +/** + * send 1 byte blocking + * return readed byte on success + */ +uint8_t spi_write_byte(uint8_t data){ + while(!(SPI_SR(SPI1) & SPI_SR_TXE)); + SPI_DR(SPI1) = data; + while(!(SPI_SR(SPI1) & SPI_SR_TXE)); + while(!(SPI_SR(SPI1) & SPI_SR_RXNE)); + uint8_t rd = SPI_DR(SPI1); + while(!(SPI_SR(SPI1) & SPI_SR_TXE)); + while(SPI_SR(SPI1) & SPI_SR_BSY); + return rd; +} + + diff --git a/canon_lens/spi.h b/canon_lens/spi.h new file mode 100644 index 0000000..e0d4be6 --- /dev/null +++ b/canon_lens/spi.h @@ -0,0 +1,31 @@ +/* + * spi.h + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __SPI_H__ +#define __SPI_H__ + +void SPI_init(); +uint8_t spiWrite(uint8_t *data, uint16_t len); +extern uint32_t Current_SPI; +uint8_t spi_write_byte(uint8_t data); + +#endif // __SPI_H__ diff --git a/canon_lens/sync.c b/canon_lens/sync.c new file mode 100644 index 0000000..ba688c3 --- /dev/null +++ b/canon_lens/sync.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* + * TODO: + * implement mutexes for other type of MCU (which doesn't have strex & ldrex) + */ + +#include + +/* DMB is supported on CM0 */ +void __dmb() +{ + __asm__ volatile ("dmb"); +} + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("ldrex %0, [%1]" : "=r" (res) : "r" (addr)); + return res; +} + +uint32_t __strex(uint32_t val, volatile uint32_t *addr) +{ + uint32_t res; + __asm__ volatile ("strex %0, %2, [%1]" + : "=&r" (res) : "r" (addr), "r" (val)); + return res; +} + +void mutex_lock(mutex_t *m) +{ + uint32_t status = 0; + + do { + /* Wait until the mutex is unlocked. */ + while (__ldrex(m) != MUTEX_UNLOCKED); + + /* Try to acquire it. */ + status = __strex(MUTEX_LOCKED, m); + + /* Did we get it? If not then try again. */ + } while (status != 0); + + /* Execute the mysterious Data Memory Barrier instruction! */ + __dmb(); +} + +void mutex_unlock(mutex_t *m) +{ + /* Ensure accesses to protected resource are finished */ + __dmb(); + + /* Free the lock. */ + *m = MUTEX_UNLOCKED; +} + +/* + * Try to lock mutex + * if it's already locked or there was error in STREX, return MUTEX_LOCKED + * else return MUTEX_UNLOCKED + */ +mutex_t mutex_trylock(mutex_t *m){ + uint32_t status = 0; + mutex_t old_lock = __ldrex(m); // get mutex value + // set mutex + status = __strex(MUTEX_LOCKED, m); + if(status == 0) __dmb(); + else old_lock = MUTEX_LOCKED; + return old_lock; +} + +#endif diff --git a/canon_lens/sync.h b/canon_lens/sync.h new file mode 100644 index 0000000..bfe837b --- /dev/null +++ b/canon_lens/sync.h @@ -0,0 +1,53 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Fergus Noble + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CM3_SYNC_H +#define LIBOPENCM3_CM3_SYNC_H + +void __dmb(void); + +/* Implements synchronisation primitives as discussed in the ARM document + * DHT0008A (ID081709) "ARM Synchronization Primitives" and the ARM v7-M + * Architecture Reference Manual. +*/ + +/* --- Exclusive load and store instructions ------------------------------- */ + +/* Those are defined only on CM3 or CM4 */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + +uint32_t __ldrex(volatile uint32_t *addr); +uint32_t __strex(uint32_t val, volatile uint32_t *addr); + +/* --- Convenience functions ----------------------------------------------- */ + +/* Here we implement some simple synchronisation primitives. */ + +typedef uint32_t mutex_t; + +#define MUTEX_UNLOCKED 0 +#define MUTEX_LOCKED 1 + +void mutex_lock(mutex_t *m); +void mutex_unlock(mutex_t *m); +mutex_t mutex_trylock(mutex_t *m); + +#endif + +#endif diff --git a/canon_lens/user_proto.c b/canon_lens/user_proto.c new file mode 100644 index 0000000..6cb3e5b --- /dev/null +++ b/canon_lens/user_proto.c @@ -0,0 +1,250 @@ +/* + * user_proto.c + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "cdcacm.h" +#include "main.h" +#include "hardware_ini.h" +#include "spi.h" + +void help(){ + P("c\tmax close diaphragm\n"); + P("D\tdiaphragm 10+\n"); + P("d\tdiaphragm 10-\n"); + P("F\tmove F to 127 steps+\n"); + P("f\tmove F to 127 steps-\n"); + P("h\tshow this help\n"); + P("o\tmax open diaphragm\n"); + P("r\t(or empty line) repeat last command sequence\n"); + P("v\tshow focus value (in steps)\n"); + P("+\tgo to infinity\n"); + P("-\tgo to minimal F\n"); +} + +#define UBUFF_LEN (64) +uint8_t ubuff[UBUFF_LEN]; +int ubuff_sz = 0; + +// read unsigned char in oct,dec or hex format; if success, return 0; otherwice return 1 +// modify `buf` to point at last non-digit symbol +int read_uchar(uint8_t **buf, uint8_t *eol){ + uint8_t *start = *buf; + uint32_t readed = 0; + if(*start == '0'){ // hex or oct + if(start[1] == 'x'){ // hex + start += 2; + while(start < eol){ + char ch = *start, m = 0; + if(ch >= '0' && ch <= '9') m = '0'; + else if(ch >= 'a' && ch <= 'f') m = 'a' - 10; + else if(ch >= 'A' && ch <= 'F') m = 'A' - 10; + else break; + if(m){ + readed <<= 4; + readed |= ch - m; + } + ++start; + } + }else{ // oct + ++start; + while(start < eol){ + char ch = *start; + if(ch >= '0' && ch < '8'){ + readed <<= 3; + readed |= ch - '0'; + }else break; + ++start; + } + } + }else{ // dec + while(start < eol){ + char ch = *start; + if(ch >= '0' && ch <= '9'){ + readed *= 10; + readed += ch - '0'; + }else break; + ++start; + } + } + if(readed > 255){ + P("bad value!"); + return 1; + } + ubuff[ubuff_sz++] = (uint8_t) readed; + *buf = start; + return 0; +} + +static const uint8_t gotoplus[] = {0, 10, 7, 5, 0}; +static const uint8_t gotominus[] = {0, 10, 7, 6, 0}; +static const uint8_t diaopen[] = {0, 10, 19, 128, 0}; +static const uint8_t diaclose[] = {0, 10, 19, 127, 0}; +static const uint8_t diap[] = {0, 10, 19, ~10, 8, 0}; +static const uint8_t diam[] = {0, 10, 19, 10, 8, 0}; +static const uint8_t fmovp[] = {0, 10, 7, 68, 0, 127, 0}; +static const uint8_t fmovm[] = {0, 10, 7, 68, 255, 128, 0}; + + +void write_buff(uint8_t *buf, int len){ + int i; + for(i = 0; i < len; ++i){ + uint8_t rd = spi_write_byte(buf[i]); + print_int(i); P(": written "); print_int(buf[i]); + P(" readed "); print_int(rd); newline(); + Delay(2); + } +} + +void showFval(){ + int16_t val; + uint8_t rd = 0, *b = (uint8_t*)&val; + int i; + for(i = 0; i < 3 && rd != 0xaa; ++i){ + spi_write_byte(10); + Delay(2); + rd = spi_write_byte(0); + Delay(5); + } + if(rd != 0xaa){ + P("Something wrong: lens don't answer!\n"); + return; + } + spi_write_byte(192); + Delay(2); + b[1] = spi_write_byte(0); + Delay(2); + b[0] = spi_write_byte(0); + P("focus motor position: "); + print_int(val); + newline(); +} + +/** + * parce command buffer buf with length len + * fill uint8_t data buffer with readed data + */ +void parse_incoming_buf(){ + uint8_t *curch = usbdatabuf, *eol = usbdatabuf + usbdatalen; + uint8_t ch = *curch, data = 0; + if(usbdatalen == 2){ + switch(ch){ + case 'h': // help + help(); + break; + case 'r': // repeat last command + write_buff(ubuff, ubuff_sz); + break; +#define WRBUF(x) do{write_buff((uint8_t*)x, sizeof(x));}while(0) + case '+': // goto infty + WRBUF(gotoplus); + break; + case '-': // goto 2.5m + WRBUF(gotominus); + break; + case 'o': // open d + WRBUF(diaopen); + break; + case 'c': // close d + WRBUF(diaclose); + break; + case 'F': // f127+ + WRBUF(fmovp); + break; + case 'f': // f127- + WRBUF(fmovm); + break; + case 'd': + WRBUF(diam); + break; + case 'D': + WRBUF(diap); + break; + case 'v': + showFval(); + break; + } + empty_buf(); + return; + } + while(curch < eol){ + ch = *curch; + if(ch >= '0' && ch <= '9'){ + if(!data){data = 1; ubuff_sz = 0;} + if(read_uchar(&curch, eol)){ + ubuff_sz = 0; + break; + } + continue; + } + ++curch; + } + write_buff(ubuff, ubuff_sz); + if(eol[-1] != '\n') P("Warning! Buffer overflow, some data may be corrupt!!!"); + empty_buf(); +} + +/** + * Send char array wrd thru USB + */ +void prnt(uint8_t *wrd){ + if(!wrd) return; + while(*wrd) usb_send(*wrd++); +} + +/** + * Print buff as hex values + * @param buf - buffer to print + * @param l - buf length + * @param s - function to send a byte + */ +void print_hex(uint8_t *buff, uint8_t l){ + void putc(uint8_t c){ + if(c < 10) + usb_send(c + '0'); + else + usb_send(c + 'a' - 10); + } + usb_send('0'); usb_send('x'); // prefix 0x + while(l--){ + putc(buff[l] >> 4); + putc(buff[l] & 0x0f); + } +} + +/** + * Print decimal integer value + * @param N - value to print + * @param s - function to send a byte + */ +void print_int(int32_t N){ + uint8_t buf[10], L = 0; + if(N < 0){ + usb_send('-'); + N = -N; + } + if(N){ + while(N){ + buf[L++] = N % 10 + '0'; + N /= 10; + } + while(L--) usb_send(buf[L]); + }else usb_send('0'); +} + diff --git a/canon_lens/user_proto.h b/canon_lens/user_proto.h new file mode 100644 index 0000000..1cf3c76 --- /dev/null +++ b/canon_lens/user_proto.h @@ -0,0 +1,47 @@ +/* + * user_proto.h + * + * Copyright 2014 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __USER_PROTO_H__ +#define __USER_PROTO_H__ + +#include "cdcacm.h" + +// shorthand for prnt +#define P(arg) do{prnt((uint8_t*)arg);}while(0) +// debug message - over USB +#ifdef EBUG + #define DBG(a) do{prnt((uint8_t*)a);}while(0) +#else + #define DBG(a) +#endif + +typedef uint8_t (*intfun)(int32_t); + +void prnt(uint8_t *wrd); +#define newline() usb_send('\n') + +void print_int(int32_t N); +void print_hex(uint8_t *buff, uint8_t l); + +void parse_incoming_buf(); + +#endif // __USER_PROTO_H__