1
0
mirror of https://github.com/rene-dev/stmbl.git synced 2024-12-24 17:42:10 +00:00

initial port to libopencm3

This commit is contained in:
Rene Hopf 2016-02-26 15:59:17 +01:00
parent b3e5f42439
commit 3643b09c8d
14 changed files with 932 additions and 559 deletions

View File

@ -1,8 +1,8 @@
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
#
OPT = -O1 -flto
# OPT = -O1 # for debugging
#OPT = -O1 -flto
OPT = -ggdb3 # for debugging
# Object files directory
# Warning: this will be removed by make clean!
@ -17,72 +17,24 @@ INCDIRS += inc
INCDIRS += shared
SOURCES += src/main.c
SOURCES += src/stm32f4xx_it.c
SOURCES += src/system_stm32f4xx.c
SOURCES += src/scanf.c
SOURCES += src/setup.c
SOURCES += src/usb_cdc.c
SOURCES += src/cdc.c
SOURCES += src/hal.c
SOURCES += src/misc.c
SOURCES += src/eeprom.c
#SOURCES += src/eeprom.c
SOURCES += src/link.c
SOURCES += src/version.c
SOURCES += src/syscalls.c
SOURCES += shared/crc8.c
SOURCES += shared/common.c
SOURCES += shared/ringbuf.c
USB_VCP_DIR = lib/STM32_USB_Device_VCP-1.2.0
LDFLAGS += -lopencm3_stm32f4 -Llibopencm3/lib/ -nostartfiles
CFLAGS += -DSTM32F4
INCDIRS += libopencm3/include
CPPFLAGS += -DUSBD_PRODUCT_STRING='"STMBL Virtual ComPort"'
CPPFLAGS += -DCDC_IN_FRAME_INTERVAL=1
CPPFLAGS += -DAPP_RX_DATA_SIZE=4096
INCDIRS += $(USB_VCP_DIR)/inc
SOURCES += $(USB_VCP_DIR)/src/usbd_desc.c
USB_DEVICE_DIR = lib/STM32_USB_Device_Library-1.2.0
INCDIRS += $(USB_DEVICE_DIR)/Class/cdc/inc
SOURCES += $(USB_DEVICE_DIR)/Class/cdc/src/usbd_cdc_core.c
INCDIRS += $(USB_DEVICE_DIR)/Core/inc
SOURCES += $(USB_DEVICE_DIR)/Core/src/usbd_core.c
SOURCES += $(USB_DEVICE_DIR)/Core/src/usbd_ioreq.c
SOURCES += $(USB_DEVICE_DIR)/Core/src/usbd_req.c
USB_DRIVER_DIR = lib/STM32_USB_OTG_Driver-2.2.0
INCDIRS += $(USB_DRIVER_DIR)/inc
SOURCES += $(USB_DRIVER_DIR)/src/usb_core.c
SOURCES += $(USB_DRIVER_DIR)/src/usb_dcd.c
SOURCES += $(USB_DRIVER_DIR)/src/usb_dcd_int.c
# Standard peripheral library
CPPFLAGS += -DUSE_STDPERIPH_DRIVER
#CPPFLAGS += -DUSE_FULL_ASSERT
PERIPH_DRV_DIR = lib/STM32F4xx_StdPeriph_Driver-V1.6.0
INCDIRS += $(PERIPH_DRV_DIR)/inc
INCDIRS += lib/CMSIS/Include
INCDIRS += lib/CMSIS/Device/ST/STM32F4xx/Include
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_adc.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_crc.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_dma.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_flash.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_gpio.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_pwr.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_rcc.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_tim.c
SOURCES += $(PERIPH_DRV_DIR)/src/stm32f4xx_usart.c
SOURCES += $(PERIPH_DRV_DIR)/src/misc.c
SOURCES += lib/CMSIS/Device/ST/STM32F4xx/Source/startup_stm32f40_41xxx.s
CPPFLAGS += -DSTM32F40_41xxx
CPPFLAGS += -DHSE_VALUE=8000000
LDSCRIPT = stm32_flash.ld
#============================================================================
@ -96,7 +48,6 @@ CPPFLAGS += $(addprefix -I,$(INCDIRS))
# -save-temps preserve .s and .i-files
#
CPPFLAGS += -fsingle-precision-constant
CPPFLAGS += -g
# CPPFLAGS += -save-temps=obj
#---------------- C Compiler Options ----------------
@ -194,6 +145,9 @@ boot_clean:
boot_flash: boot
$(MAKE) -f bootloader/Makefile flash
flash:
st-flash --reset write $(TARGET).bin 0x08000000
hv_flash: boot
$(MAKE) -f stm32f103/Makefile flash

96
shared/ringbuf.c Normal file
View File

@ -0,0 +1,96 @@
#include "ringbuf.h"
/**
* Read a single byte from a buffer
*
* \param rb pointer to ringbuffer struct
* \param data pointer to data byte
* \return number of bytes read (0 if buffer was empty)
*/
int rb_getc(struct ringbuf *rb, char *data)
{
if (!rb->len)
return 0;
*data = rb->buf[rb->pos++];
if (rb->pos >= rb->bufsize)
rb->pos -= rb->bufsize;
rb->len--;
return 1;
}
/**
* Write a single byte to a buffer
*
* \param rb pointer to ringbuffer struct
* \param data pointer to data byte
* \return number of bytes written (0 if buffer was full)
*/
int rb_putc(struct ringbuf *rb, const char data)
{
if (rb->len >= rb->bufsize)
return 0;
unsigned i = rb->pos + rb->len;
if (i >= rb->bufsize)
i -= rb->bufsize;
rb->buf[i] = data;
rb->len++;
return 1;
}
/**
* Read from a buffer
*
*/
int rb_read(struct ringbuf *rb, void *data, int len)
{
if (len > rb->len)
len = rb->len;
int len1 = len;
if (rb->pos + len1 >= rb->bufsize) {
int len2 = (rb->pos + len1) - rb->bufsize;
len1 -= len2;
memcpy((char*)data + len1, rb->buf, len2);
}
memcpy(data, rb->buf + rb->pos, len1);
rb->len -= len;
rb->pos += len;
if (rb->pos > rb->bufsize)
rb->pos -= rb->bufsize;
return len;
}
/**
* Write to a buffer
*
* \param rb pointer to ringbuffer struct
* \param data pointer to data byte
* \return number of bytes written (0 if buffer was full)
*
*/
int rb_write(struct ringbuf *rb, const void *data, int len)
{
if (len > rb->bufsize - rb->len)
len = rb->bufsize - rb->len;
int len1 = len;
if (rb->pos + rb->len + len1 >= rb->bufsize) {
int len2 = (rb->pos + rb->len + len1) - rb->bufsize;
len1 -= len2;
memcpy(rb->buf, (char*)data + len1, len2);
}
memcpy(rb->buf + rb->pos + rb->len, data, len1);
rb->len += len;
return len;
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <string.h>
/**
* Ringbuffer structure
@ -21,18 +21,7 @@ struct ringbuf {
* \param data pointer to data byte
* \return number of bytes read (0 if buffer was empty)
*/
static inline int rb_getc(struct ringbuf *rb, char *data)
{
if (!rb->len)
return 0;
*data = rb->buf[rb->pos++];
if (rb->pos >= rb->bufsize)
rb->pos -= rb->bufsize;
rb->len--;
return 1;
}
int rb_getc(struct ringbuf *rb, char *data);
/**
@ -42,47 +31,12 @@ static inline int rb_getc(struct ringbuf *rb, char *data)
* \param data pointer to data byte
* \return number of bytes written (0 if buffer was full)
*/
static inline int rb_putc(struct ringbuf *rb, const char data)
{
if (rb->len >= rb->bufsize)
return 0;
unsigned i = rb->pos + rb->len;
if (i >= rb->bufsize)
i -= rb->bufsize;
rb->buf[i] = data;
rb->len++;
return 1;
}
#if 0
int rb_putc(struct ringbuf *rb, const char data);
/**
* Read from a buffer
*
*/
int rb_read(struct ringbuf *rb, void *data, int len)
{
if (len > rb->len)
len = rb->len;
int len1 = len;
if (rb->pos + len1 >= rb->bufsize) {
int len2 = (rb->pos + len1) - rb->bufsize;
len1 -= len2;
memcpy((char*)data + len1, rb->buf, len2);
}
memcpy(data, rb->buf + rb->pos, len1);
rb->len -= len;
rb->pos += len;
if (rb->pos > rb->bufsize)
rb->pos -= rb->bufsize;
return len;
}
int rb_read(struct ringbuf *rb, void *data, int len);
/**
@ -93,22 +47,4 @@ int rb_read(struct ringbuf *rb, void *data, int len)
* \return number of bytes written (0 if buffer was full)
*
*/
int rb_write(struct ringbuf *rb, const void *data, int len)
{
if (len > rb->bufsize - rb->len)
len = rb->bufsize - rb->len;
int len1 = len;
if (rb->pos + rb->len + len1 >= rb->bufsize) {
int len2 = (rb->pos + rb->len + len1) - rb->bufsize;
len1 -= len2;
memcpy(rb->buf, (char*)data + len1, len2);
}
memcpy(rb->buf + rb->pos + rb->len, data, len1);
rb->len += len;
return len;
}
#endif
int rb_write(struct ringbuf *rb, const void *data, int len);

314
src/cdc.c Normal file
View File

@ -0,0 +1,314 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/scb.h>
#include "cdc.h"
struct ringbuf rx_buf = { .buf = (char[RX_QUEUE_SIZE]) {0}, .bufsize = RX_QUEUE_SIZE };
struct ringbuf tx_buf = { .buf = (char[TX_QUEUE_SIZE]) {0}, .bufsize = TX_QUEUE_SIZE };
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,
};
/*
* This notification endpoint isn't implemented. According to CDC spec it's
* optional, but its absence causes a NULL pointer dereference in the
* 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,
};
//TODO: serial number
//https://github.com/rene-dev/stmbl/blob/master/lib/STM32_USB_Device_VCP-1.2.0/src/usbd_desc.c#L302-L314
//https://github.com/paparazzi/paparazzi/blob/master/sw/airborne/arch/stm32/usb_ser_hw.c#L516
static const char * usb_strings[] = {
"Black Sphere Technologies",
"STMBL Virtual ComPort",
"DEMO",//serial
};
/* Buffer to be used for control requests. */
uint8_t usbd_control_buffer[128];
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;
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
/*
* 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.
*/
char local_buf[10];
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);
return 1;
}
case USB_CDC_REQ_SET_LINE_CODING:
if (*len < sizeof(struct usb_cdc_line_coding)) {
return 0;
}
return 1;
}
return 0;
}
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
{
//gpio_toggle(GPIOB,GPIO8);
(void)ep;
char buf[64];
int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
rb_write(&rx_buf, buf, len);
}
void cdcacm_flush(){
}
int cdcacm_tx(void* data, uint32_t len){
if(usb_connected == 0){
return 0;
}
int ret, len2;
char buf[64];
ret = rb_write(&tx_buf, data, len);
if(!usbd_ep_stall_get(usbd_dev, 0.82) && tx_buf.len > 0){
len2 = rb_read(&tx_buf,buf,64);
usbd_ep_write_packet(usbd_dev, 0x82, buf,len2);
}
return ret;
}
static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep)
{
if(usb_connected == 0){
return;
}
char buf[64];
int len;
if(tx_buf.len > 0){
len = rb_read(&tx_buf,buf,64);
usbd_ep_write_packet(usbd_dev, 0x82, buf,len);
}
}
int cdcacm_is_connected(){
return usb_connected;
}
//TODO: ptr overflow
int cdcacm_getstring(char *ptr){
int len = 0;
char c;
if (rx_buf.len == 0) return 0;
while(rb_getc(&rx_buf, &c)){
len++;
*ptr++ = c;
if(c == 0x0D){
*--ptr = 0x00;
return len;
}
}
}
// use suspend callback to detect disconnect
static void suspend_cb(void)
{
usb_connected = 0;
gpio_clear(GPIOC, GPIO10);
}
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
{
(void)wValue;
usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, 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);
usb_connected = 1;
tx_buf.len = 0;
rx_buf.len = 0;
gpio_set(GPIOC, GPIO10);
usbd_register_suspend_callback(usbd_dev, suspend_cb);
}
void cdc_init(void)
{
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_OTGFS);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO11 | GPIO12);
usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
usb_connected = 0;
}

20
src/cdc.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
#include "ringbuf.h"
#define RX_QUEUE_SIZE 512
#define TX_QUEUE_SIZE 512
void cdc_init(void);
int cdcacm_tx(void* data, uint32_t len);
int cdcacm_getstring(char *ptr);
int cdcacm_is_connected();
void cdcacm_flush();
usbd_device *usbd_dev;
int usb_connected;
extern struct ringbuf rx_buf;
extern struct ringbuf tx_buf;

View File

@ -60,7 +60,7 @@ MEM(unsigned int last_fault_sent) = 0; //save last error message
MEM(uint32_t last_hal_state) = HAL_OK;
MEM(uint16_t ee_error);
/*
int load(){
if(hal.rt_state != RT_STOP || hal.frt_state != FRT_STOP){
return(-4);
@ -104,9 +104,10 @@ int load(){
update_fb();
return 0;
}
*/
INIT(
/*
FLASH_Unlock();
ee_error = EE_Init();
FLASH_Lock();
@ -114,10 +115,11 @@ INIT(
if(ret){//flash load error
hal.hal_state = CONFIG_LOAD_ERROR;
}
*/
);
RT(
TIM2->ARR = (int)CLAMP(PIN(tim2_rv), 1, 1500);
TIM2_ARR = (int)CLAMP(PIN(tim2_rv), 1, 1500);
if(send_counter++ >= PIN(send_step) - 1){
w0[write_pos] = PIN(wave0);
w1[write_pos] = PIN(wave1);
@ -138,11 +140,11 @@ NRT(
void bootloader(){
*((unsigned long *)0x2001C000) = 0xDEADBEEF;
NVIC_SystemReset();
scb_reset_system();
}
void reset(){
NVIC_SystemReset();
scb_reset_system();
}
void hal_info(){
@ -298,16 +300,15 @@ NRT(
printf("by %s on %s\n",version_info.build_user, version_info.build_host);
printf("GCC %s\n",__VERSION__);
printf("newlib %s\n",_NEWLIB_VERSION);
printf("CMSIS %i.%i\n",__CM4_CMSIS_VERSION_MAIN,__CM4_CMSIS_VERSION_SUB);
printf("StdPeriph %i.%i.%i\n",__STM32F4XX_STDPERIPH_VERSION_MAIN,__STM32F4XX_STDPERIPH_VERSION_SUB1,__STM32F4XX_STDPERIPH_VERSION_SUB2);
printf("CPU ID %lx %lx %lx\n",U_ID[0], U_ID[1], U_ID[2]);
CRC_ResetDR();
uint32_t crc = CRC_CalcBlockCRC((uint32_t *) 0x08010000, version_info.image_size / 4);
//TODO
//CRC_ResetDR();
//uint32_t crc = CRC_CalcBlockCRC((uint32_t *) 0x08010000, version_info.image_size / 4);
printf("size: %lu crc:%lx\n", version_info.image_size, version_info.image_crc);
if(crc == 0)
printf("crc ok!\n");
else
printf("crc error!:%lx\n", crc);
//if(crc == 0)
// printf("crc ok!\n");
//else
// printf("crc error!:%lx\n", crc);
printf("######## Bootloader info ########\n");
printf(
@ -339,43 +340,43 @@ NRT(
void sysinfo(){
printf("######## sysinfo ########\n");
extern char _etext; // end address of the .text section
extern char _sidata; // start address of the initialization values of the .data section
extern char _sdata; // start address of the .data section
extern char _edata; // end address of the .data section
extern char _sbss; // start address of the .bss section
extern char _ebss; // end address of the .bss section
// extern char _etext; // end address of the .text section
// extern char _sidata; // start address of the initialization values of the .data section
// extern char _sdata; // start address of the .data section
// extern char _edata; // end address of the .data section
// extern char _sbss; // start address of the .bss section
// extern char _ebss; // end address of the .bss section
//extern char _snoinit; // start address of the .noinit section
//extern char _enoinit; // end address of the .noinit section
extern char _end; // end address of the .bss section
extern char _estack; // initial value of the stack pointer
// extern char _end; // end address of the .bss section
// extern char _estack; // initial value of the stack pointer
//
// extern char *__brkval;
extern char *__brkval;
//RCC_ClocksTypeDef RCC_ClocksStatus;
//RCC_GetClocksFreq(&RCC_ClocksStatus);
RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);
printf("HSE_VALUE = %uHz\n", HSE_VALUE);
printf("SYSCLK_Frequency = %luHz\n", RCC_ClocksStatus.SYSCLK_Frequency );
printf("HCLK_Frequency = %luHz\n", RCC_ClocksStatus.HCLK_Frequency );
printf("PCLK1_Frequency = %luHz\n", RCC_ClocksStatus.PCLK1_Frequency );
printf("PCLK2_Frequency = %luHz\n", RCC_ClocksStatus.PCLK2_Frequency );
extern void *g_pfnVectors;
printf("vtor %lu\n",(uint32_t)&g_pfnVectors);
// printf("HSE_VALUE = %uHz\n", HSE_VALUE);
// printf("SYSCLK_Frequency = %luHz\n", RCC_ClocksStatus.SYSCLK_Frequency );
// printf("HCLK_Frequency = %luHz\n", RCC_ClocksStatus.HCLK_Frequency );
// printf("PCLK1_Frequency = %luHz\n", RCC_ClocksStatus.PCLK1_Frequency );
// printf("PCLK2_Frequency = %luHz\n", RCC_ClocksStatus.PCLK2_Frequency );
//extern void *g_pfnVectors;
//printf("vtor %lu\n",(uint32_t)&g_pfnVectors);
//*****************************************************************
printf("RCC->CSR = %x\n", (unsigned int)RCC->CSR);
printf("_etext = %p\n", &_etext );
printf("_sidata = %p\n", &_sidata );
printf("_sdata = %p\n", &_sdata );
printf("_edata = %p\n", &_edata );
printf("_sbss = %p\n", &_sbss );
printf("_ebss = %p\n", &_ebss );
//printf("RCC->CSR = %x\n", (unsigned int)RCC_CSR);
// printf("_etext = %p\n", &_etext );
// printf("_sidata = %p\n", &_sidata );
// printf("_sdata = %p\n", &_sdata );
// printf("_edata = %p\n", &_edata );
// printf("_sbss = %p\n", &_sbss );
// printf("_ebss = %p\n", &_ebss );
// printf("_snoinit = %p\n", &_snoinit);
// printf("_enoinit = %p\n", &_enoinit);
printf("_end = %p\n", &_end );
printf("_estack = %p\n", &_estack );
// printf("_end = %p\n", &_end );
// printf("_estack = %p\n", &_estack );
printf("heap avail = %luB\n", (uint32_t)((char*)__get_MSP() - __brkval));
// printf("heap avail = %luB\n", (uint32_t)((char*)__get_MSP() - __brkval));
}
void listhal(){
@ -384,7 +385,7 @@ NRT(
Wait(1);
}
}
/*
void save(){
if(ee_error != FLASH_COMPLETE){
printf("flash error:%i\n",ee_error);
@ -423,6 +424,7 @@ NRT(
FLASH_Lock();
printf("done\n");
}
*/
void conf(){
for(int i = 0; i < hal.hal_pin_count; i++){
@ -434,7 +436,7 @@ NRT(
}
}
}
/*
void load_cmd(){
int ret = load();
if(ret == -1){
@ -451,7 +453,7 @@ NRT(
printf("done\n");
}
}
*/
void help(){
printf("######## HAL cheat sheet ########\n");
printf("pin name: <comp name><comp instance number>.<pin name> (e.g. pid0.enable)\n");
@ -503,16 +505,20 @@ NRT(
help();
}
else if(!strcmp(s, "save")){
save();
//TODO:
//save();
printf("not implemented\n");
}
else if(!strcmp(s, "load")){
load_cmd();
//TODO:
//load_cmd();
printf("not implemented\n");
}
else if(!strcmp(s, "conf")){
conf();
}
else{
printf("not found: %s\n",s);
printf("cmd not found: %s\n",s);
}
}
@ -657,9 +663,9 @@ NRT(
buf[8 + 1] = 0;
if (USB_CDC_is_connected()) {
if (cdcacm_is_connected()) {
PIN(con) = 1.0;
USB_VCP_send_string(buf);
cdcacm_tx(buf,9);
}else{
PIN(con) = 0.0;
}
@ -669,16 +675,16 @@ NRT(
if (USB_CDC_is_connected() && systime >= 1000) {
char source[APP_TX_BUF_SIZE];
char sink[APP_TX_BUF_SIZE];
if (cdcacm_is_connected()) {
char source[MAX_HPNAME];
char sink[MAX_HPNAME];
fault_sender();
hal_error_sender();
int i = -1;
char rx_buf[APP_TX_BUF_SIZE];
if (USB_VCP_get_string(rx_buf)) {
char rx_buf[65];
if (cdcacm_getstring(rx_buf)) {
i = sscanf_(rx_buf, "%N = %N", sink, source);
}
if(i == 2){ // read hal pin

View File

@ -198,24 +198,24 @@ extern void disable_frt();
#define RT(func) \
self.rt = ({ void function(float period){ \
unsigned int __start_time__ = SysTick->VAL; \
unsigned int __start_time__ = systick_get_value(); \
func \
unsigned int __end_time__ = SysTick->VAL; \
unsigned int __end_time__ = systick_get_value(); \
if(__start_time__ < __end_time__){ \
__start_time__ += SysTick->LOAD; \
__start_time__ += systick_get_reload(); \
} \
PIN(rt_calc_time) = ((float)(__start_time__ - __end_time__)) / RCC_Clocks.HCLK_Frequency; \
PIN(rt_calc_time) = ((float)(__start_time__ - __end_time__)) / rcc_ahb_frequency; \
} function;});
#define FRT(func) \
self.frt = ({ void function(float period){ \
unsigned int __start_time__ = SysTick->VAL; \
unsigned int __start_time__ = systick_get_value(); \
func \
unsigned int __end_time__ = SysTick->VAL; \
unsigned int __end_time__ = systick_get_value(); \
if(__start_time__ < __end_time__){ \
__start_time__ += SysTick->LOAD; \
__start_time__ += systick_get_reload(); \
} \
PIN(frt_calc_time) = ((float)(__start_time__ - __end_time__)) / RCC_Clocks.HCLK_Frequency; \
PIN(frt_calc_time) = ((float)(__start_time__ - __end_time__)) / rcc_ahb_frequency; \
} function;});
#define NRT(func) \

View File

@ -18,18 +18,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stm32f4xx_conf.h"
#include "scanf.h"
#include "hal.h"
#include "setup.h"
#include "eeprom.h"
//#include "eeprom.h"
#include "link.h"
#include "crc8.h"
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "usb_cdc.h"
GLOBAL_HAL_PIN(rt_time);
@ -41,16 +39,16 @@ void Wait(uint32_t ms);
//hal interface
void enable_rt(){
TIM_Cmd(TIM2, ENABLE);
timer_enable_counter(TIM2);
}
void enable_frt(){
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
timer_enable_irq(TIM2,TIM_DIER_UIE);
}
void disable_rt(){
TIM_Cmd(TIM2, DISABLE);
timer_disable_counter(TIM2);
}
void disable_frt(){
TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
timer_disable_irq(TIM2,TIM_DIER_UIE);
}
extern char _binary_obj_hv_hv_bin_start;
@ -65,8 +63,8 @@ void SysTick_Handler(void)
}
//20kHz
void TIM2_IRQHandler(void){
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
void tim2_isr(void){
timer_clear_flag(TIM2,TIM_SR_UIF);
switch(hal.frt_state){
case FRT_STOP:
return;
@ -85,16 +83,16 @@ void TIM2_IRQHandler(void){
hal.frt_state = FRT_CALC;
}
GPIO_SetBits(GPIOB,GPIO_Pin_9);
gpio_set(GPIOB,GPIO9);
static unsigned int last_start = 0;
unsigned int start = SysTick->VAL;
unsigned int start = systick_get_value();
if(last_start < start){
last_start += SysTick->LOAD;
last_start += systick_get_reload();
}
float period = ((float)(last_start - start)) / RCC_Clocks.HCLK_Frequency;
float period = ((float)(last_start - start)) / rcc_ahb_frequency;
last_start = start;
for(hal.active_frt_func = 0; hal.active_frt_func < hal.frt_func_count; hal.active_frt_func++){//run all fast realtime hal functions
@ -102,21 +100,21 @@ void TIM2_IRQHandler(void){
}
hal.active_frt_func = -1;
unsigned int end = SysTick->VAL;
unsigned int end = systick_get_value();
if(start < end){
start += SysTick->LOAD;
start += systick_get_reload();
}
PIN(frt_time) = ((float)(start - end)) / RCC_Clocks.HCLK_Frequency;
PIN(frt_time) = ((float)(start - end)) / rcc_ahb_frequency;
PIN(frt_period_time) = period;
hal.frt_state = FRT_SLEEP;
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
gpio_clear(GPIOB,GPIO9);
}
//5 kHz interrupt for hal. at this point all ADCs have been sampled,
//see setup_res() in setup.c if you are interested in the magic behind this.
void DMA2_Stream0_IRQHandler(void){
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
void dma2_stream0_isr(void){
dma_clear_interrupt_flags(DMA2, DMA_STREAM0, DMA_TCIF);
switch(hal.rt_state){
case RT_STOP:
return;
@ -135,16 +133,16 @@ void DMA2_Stream0_IRQHandler(void){
hal.rt_state = RT_CALC;
}
GPIO_SetBits(GPIOB,GPIO_Pin_8);
gpio_set(GPIOB,GPIO8);
static unsigned int last_start = 0;
unsigned int start = SysTick->VAL;
unsigned int start = systick_get_value();
if(last_start < start){
last_start += SysTick->LOAD;
last_start += systick_get_reload();
}
float period = ((float)(last_start - start)) / RCC_Clocks.HCLK_Frequency;
float period = ((float)(last_start - start)) / rcc_ahb_frequency;
last_start = start;
for(hal.active_rt_func = 0; hal.active_rt_func < hal.rt_func_count; hal.active_rt_func++){//run all realtime hal functions
@ -152,23 +150,24 @@ void DMA2_Stream0_IRQHandler(void){
}
hal.active_rt_func = -1;
unsigned int end = SysTick->VAL;
unsigned int end = systick_get_value();
if(start < end){
start += SysTick->LOAD;
start += systick_get_reload();
}
PIN(rt_time) = ((float)(start - end)) / RCC_Clocks.HCLK_Frequency;
PIN(rt_time) = ((float)(start - end)) / rcc_ahb_frequency;
PIN(rt_period_time) = period;
hal.rt_state = RT_SLEEP;
GPIO_ResetBits(GPIOB,GPIO_Pin_8);
gpio_clear(GPIOB,GPIO8);
}
int main(void)
{
rcc_clock_setup_hse_3v3(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
// Relocate interrupt vectors
//
extern void *g_pfnVectors;
SCB->VTOR = (uint32_t)&g_pfnVectors;
//extern void *vector_table;
//SCB_VTOR = (uint32_t)&vector_table;
float period = 0.0;
int last_start = 0;
@ -182,19 +181,19 @@ int main(void)
HAL_PIN(bar) = 0.0;
//feedback comps
#include "comps/adc.comp"
#include "comps/res.comp"
#include "comps/enc_fb.comp"
#include "comps/encm.comp"
#include "comps/encs.comp"
#include "comps/yaskawa.comp"
// #include "comps/adc.comp"
// #include "comps/res.comp"
// #include "comps/enc_fb.comp"
// #include "comps/encm.comp"
// #include "comps/encs.comp"
// #include "comps/yaskawa.comp"
//TODO: hyperface
//command comps
#include "comps/sserial.comp"
// #include "comps/sserial.comp"
#include "comps/sim.comp"
#include "comps/enc_cmd.comp"
#include "comps/en.comp"
// #include "comps/enc_cmd.comp"
// #include "comps/en.comp"
//PID
#include "comps/stp.comp"
@ -210,12 +209,12 @@ int main(void)
#include "comps/pmsm_limits.comp"
#include "comps/idq.comp"
#include "comps/dq.comp"
#include "comps/hv.comp"
// #include "comps/hv.comp"
//other comps
#include "comps/fault.comp"
#include "comps/term.comp"
#include "comps/io.comp"
// #include "comps/io.comp"
set_comp_type("net");
@ -316,13 +315,14 @@ int main(void)
while(1)//run non realtime stuff
{
start = SysTick->VAL;
usbd_poll(usbd_dev);
start = systick_get_value();
if(last_start < start){
last_start += SysTick->LOAD;
last_start += systick_get_reload();
}
period = ((float)(last_start - start)) / RCC_Clocks.HCLK_Frequency;
period = ((float)(last_start - start)) / rcc_ahb_frequency;
last_start = start;
for(hal.active_nrt_func = 0; hal.active_nrt_func < hal.nrt_func_count; hal.active_nrt_func++){//run all non realtime hal functions
@ -330,13 +330,13 @@ int main(void)
}
hal.active_nrt_func = -1;
end = SysTick->VAL;
end = systick_get_value();
if(start < end){
start += SysTick->LOAD;
start += systick_get_reload();
}
PIN(nrt_calc_time) = ((float)(start - end)) / RCC_Clocks.HCLK_Frequency;
PIN(nrt_calc_time) = ((float)(start - end)) / rcc_ahb_frequency;
PIN(nrt_period) = period;
Wait(2);
//Wait(2);
}
}

View File

@ -7,23 +7,23 @@
//
#include "scanf.h"
#include "usb_cdc.h"
//#include "usb_cdc.h"
int scanf_(const char *format, ...){
int ret = 0;
char rx_buf[APP_TX_BUF_SIZE];
va_list arg;
if (USB_CDC_is_connected()) {
if (USB_VCP_get_string(rx_buf)) {
va_start(arg, format);
ret = vfsscanf_(rx_buf, format, arg);
va_end(arg);
} else {
ret = -1;
}
}
return(ret);
}
// int scanf_(const char *format, ...){
// int ret = 0;
// char rx_buf[10];
// va_list arg;
// if (USB_CDC_is_connected()) {
// if (USB_VCP_get_string(rx_buf)) {
// va_start(arg, format);
// ret = vfsscanf_(rx_buf, format, arg);
// va_end(arg);
// } else {
// ret = -1;
// }
// }
// return(ret);
// }
int sscanf_(const char *buf, const char *format, ...){
int ret = 0;

View File

@ -10,7 +10,7 @@
#include <stdarg.h>
int scanf_(const char *format, ...);
//int scanf_(const char *format, ...);
int sscanf_(const char* buf, const char *format, ...);
int vfsscanf_(const char *buf, const char *format, va_list arg);
int isDecDigit(char c);

View File

@ -7,130 +7,218 @@
//
#include "setup.h"
#include "usb_cdc.h"
//#include "usb_cdc.h"
void setup(){
//Enable clocks
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_CRC, ENABLE);
//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_CRC, ENABLE);
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_GPIOD);
rcc_periph_clock_enable(RCC_DMA1);
rcc_periph_clock_enable(RCC_DMA2);
rcc_periph_clock_enable(RCC_CRC);
//messpin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3 | GPIO4 | GPIO5 | GPIO8 | GPIO9);
//gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO3 | GPIO4 | GPIO5 | GPIO8 | GPIO9);
//foo leds
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, GPIO10 | GPIO11);
gpio_set(GPIOC, GPIO11);
gpio_clear(GPIOC, GPIO10);
//foo
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//scb_set_priority_grouping();//TODO
setup_res();
usb_init();
//usb_init();
cdc_init();
// systick timer
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
//RCC_GetClocksFreq(&RCC_Clocks);
//SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
systick_set_reload(rcc_ahb_frequency / 1000);
systick_interrupt_enable();
systick_counter_enable();//??
//systick prio
NVIC_SetPriority(SysTick_IRQn, 14);
//NVIC_SetPriority(SysTick_IRQn, 14);
nvic_set_priority(NVIC_SYSTICK_IRQ,14);
nvic_enable_irq(NVIC_SYSTICK_IRQ);
}
// Setup Resolver Interface
// TIM2 triggers ADC1 and 2 at 20kHz
// TIM2 OC1 generates resolver reference signal at 10kHz
// DMA2 moves 4 samples to memory, generates transfer complete interrupt at 5kHz
void setup_res(){
//resolver timer
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
rcc_periph_clock_enable(RCC_TIM2);
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 420;//20kHz
TIM_TimeBaseStructure.TIM_Prescaler = 9;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM2,ENABLE);
// TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
// TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
// TIM_TimeBaseStructure.TIM_Period = 420;//20kHz
// TIM_TimeBaseStructure.TIM_Prescaler = 9;
// TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
// TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//TIM_ARRPreloadConfig(TIM2,ENABLE);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//trigger ADC
//timer_set_mode(TIM2,TIM_CR1_CKD_CK_INT,TIM_CR1_CMS_EDGE,TIM_CR1_DIR_UP);
timer_reset(TIM2);
timer_set_mode(TIM2,TIM_CR1_CKD_CK_INT,TIM_CR1_CMS_EDGE,TIM_CR1_DIR_UP);
timer_set_clock_division(TIM2,TIM_CR1_CKD_CK_INT);
timer_direction_up(TIM2);
timer_set_repetition_counter(TIM2,0);
//timer_enable_preload(TIM2);
timer_set_period(TIM2,420);
timer_set_prescaler(TIM2,9);
timer_enable_update_event(TIM2);
//hal does this:
//timer_enable_irq(TIM2,TIM_DIER_UIE);
//timer_enable_counter(TIM2);
//TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//trigger ADC
timer_set_master_mode(TIM2,TIM_CR2_MMS_UPDATE);
/* ADC clock enable */
RCC_APB2PeriphClockCmd(SIN_ADC_RCC | COS_ADC_RCC, ENABLE);
//RCC_APB2PeriphClockCmd(SIN_ADC_RCC | COS_ADC_RCC, ENABLE);
rcc_periph_clock_enable(RCC_ADC1);
rcc_periph_clock_enable(RCC_ADC2);
//Analog pin configuration
GPIO_InitStructure.GPIO_Pin = SIN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(SIN_PORT,&GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = SIN_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(SIN_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = COS_PIN;
GPIO_Init(COS_PORT,&GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = COS_PIN;
// GPIO_Init(COS_PORT,&GPIO_InitStructure);
gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4);
gpio_mode_setup(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO5);
//ADC structure configuration
ADC_DeInit();
//ADC_DeInit();
adc_off(ADC1);
adc_off(ADC2);
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //the conversion is continuous, the input data is converted more than once
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;//trigger on rising edge of TIM8
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_NbrOfConversion = ADC_ANZ;//I think this one is clear :p
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//The scan is configured in one channel
ADC_Init(SIN_ADC, &ADC_InitStructure);//Initialize ADC with the previous configuration
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_Init(COS_ADC, &ADC_InitStructure);//Initialize ADC with the previous configuration
// ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//data converted will be shifted to right
adc_set_right_aligned(ADC1);
adc_set_right_aligned(ADC2);
// ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit number giving a maximum value of 4096
adc_set_resolution(ADC1,ADC_CR1_RES_12BIT);
adc_set_resolution(ADC2,ADC_CR1_RES_12BIT);
// ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //the conversion is continuous, the input data is converted more than once
adc_enable_discontinuous_mode_regular(ADC1,ADC_ANZ);
adc_enable_discontinuous_mode_regular(ADC2,ADC_ANZ);
adc_disable_external_trigger_injected(ADC1);
adc_disable_external_trigger_injected(ADC2);
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;//trigger on rising edge of TIM8
// ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
adc_enable_external_trigger_regular(ADC1,ADC_CR2_EXTSEL_TIM2_TRGO,ADC_CR2_EXTEN_RISING_EDGE);//ADC2 trigger via dual mode
// ADC_InitStructure.ADC_NbrOfConversion = ADC_ANZ;//I think this one is clear :p
// ADC_InitStructure.ADC_ScanConvMode = ENABLE;//The scan is configured in one channel
adc_enable_scan_mode(ADC1);
adc_enable_scan_mode(ADC2);
// ADC_Init(SIN_ADC, &ADC_InitStructure);//Initialize ADC with the previous configuration
// ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
// ADC_Init(COS_ADC, &ADC_InitStructure);//Initialize ADC with the previous configuration
//
// ADC_CommonInitTypeDef ADC_CommonInitStructure;
// ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
// ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
adc_set_clk_prescale(ADC_CCR_ADCPRE_BY4);
// ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
//TODO: set this bit: ADC_CCR_DMA_MODE_2
ADC_CCR |= ADC_CCR_DMA_MODE_2;
ADC_CCR |= ADC_CCR_DDS;
// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
// ADC_CommonInit(&ADC_CommonInitStructure);
// for(int i = 1;i<=ADC_ANZ;i++){16
// ADC_RegularChannelConfig(SIN_ADC, SIN_ADC_CHAN, i, RES_SampleTime);14
// ADC_RegularChannelConfig(COS_ADC, COS_ADC_CHAN, i, RES_SampleTime);15
// }
//TODO: sample time?
adc_set_sample_time_on_all_channels(ADC1,ADC_SMPR_SMP_28CYC);
adc_set_sample_time_on_all_channels(ADC2,ADC_SMPR_SMP_28CYC);
uint8_t sin_ch[] = {14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14};
uint8_t cos_ch[] = {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15};
adc_set_regular_sequence(ADC1, 16, sin_ch);
adc_set_regular_sequence(ADC2, 16, cos_ch);
adc_enable_dma(ADC1);
adc_enable_dma(ADC2);
//
// ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
adc_set_multi_mode(ADC_CCR_MULTI_DUAL_REGULAR_SIMUL);
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
// //Enable ADC conversion
// ADC_Cmd(SIN_ADC,ENABLE);
adc_power_on(ADC1);
// ADC_Cmd(COS_ADC,ENABLE);
adc_power_on(ADC2);
//
// // DMA-Disable
// DMA_Cmd(DMA2_Stream0, DISABLE);
// DMA_DeInit(DMA2_Stream0);
dma_stream_reset(DMA2, DMA_STREAM0);
//
// // DMA2-Config
// DMA_InitStructure.DMA_Channel = DMA_Channel_0;
dma_channel_select(DMA2, DMA_STREAM0, DMA_SxCR_CHSEL_0);
// DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR;
dma_set_peripheral_address(DMA2, DMA_STREAM0, (uint32_t)&ADC_CDR);
// DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_DMA_Buffer;
dma_set_memory_address(DMA2, DMA_STREAM0, (uint32_t)&ADC_DMA_Buffer);
// DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
dma_set_transfer_mode(DMA2, DMA_STREAM0, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
// DMA_InitStructure.DMA_BufferSize = ADC_ANZ * PID_WAVES;
dma_set_number_of_data(DMA2, DMA_STREAM0, ADC_ANZ * PID_WAVES);
// DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_enable_memory_increment_mode(DMA2, DMA_STREAM0);
// DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
dma_set_peripheral_size(DMA2, DMA_STREAM0, DMA_SxCR_PSIZE_32BIT);
// DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
dma_set_memory_size(DMA2, DMA_STREAM0, DMA_SxCR_MSIZE_32BIT);
// DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
dma_enable_circular_mode(DMA2, DMA_STREAM0);
// DMA_InitStructure.DMA_Priority = DMA_Priority_High;
dma_set_priority(DMA2, DMA_STREAM0, DMA_SxCR_PL_HIGH);
// DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
// DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
// DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
// DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
// DMA_Init(DMA2_Stream0, &DMA_InitStructure);
for(int i = 1;i<=ADC_ANZ;i++){
ADC_RegularChannelConfig(SIN_ADC, SIN_ADC_CHAN, i, RES_SampleTime);
ADC_RegularChannelConfig(COS_ADC, COS_ADC_CHAN, i, RES_SampleTime);
}
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
//Enable ADC conversion
ADC_Cmd(SIN_ADC,ENABLE);
ADC_Cmd(COS_ADC,ENABLE);
// DMA-Disable
DMA_Cmd(DMA2_Stream0, DISABLE);
DMA_DeInit(DMA2_Stream0);
// DMA2-Config
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_DMA_Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ADC_ANZ * PID_WAVES;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
// NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
nvic_enable_irq(NVIC_TIM2_IRQ);
nvic_set_priority(NVIC_TIM2_IRQ,0);
//
// NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
nvic_enable_irq(NVIC_DMA2_STREAM0_IRQ);
nvic_set_priority(NVIC_DMA2_STREAM0_IRQ,2);
//
// DMA_Cmd(DMA2_Stream0, ENABLE);
dma_enable_stream(DMA2, DMA_STREAM0);
//
// DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
dma_enable_transfer_complete_interrupt(DMA2, DMA_STREAM0);
}

View File

@ -8,19 +8,31 @@
#pragma once
#include "stm32f4xx_conf.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/dma.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/scb.h>
#include "misc.h"
#include "version.h"
#include "common.h"
#include "defines_res.h"
#define U_ID ((__IO uint32_t *)0x1FFF7A10)
#include "cdc.h"
#define U_ID ((volatile uint32_t *)0x1FFF7A10)//TODO: should be in opencm3
//#define mag_res 5250
#define mag_res 8400
//sample times for F4: 3,15,28,56,84,112,144,480
#define RES_SampleTime ADC_SampleTime_28Cycles
//#define RES_SampleTime ADC_SampleTime_28Cycles
#define ADC_ANZ 16
#define PID_WAVES 4
@ -29,11 +41,3 @@ void setup(void);
void setup_res(void);
volatile uint32_t ADC_DMA_Buffer[ADC_ANZ * PID_WAVES];
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_ClocksTypeDef RCC_Clocks;

View File

@ -2,12 +2,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "stm32f4xx.h"
#include "usb_cdc.h"
#include "cdc.h"
//int __errno;
size_t __malloc_margin = 256;
char *__brkval;
@ -34,6 +33,14 @@ int _open(const char *name, int flags, int mode) {
/* Register name faking - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
uint32_t __get_MSP(void)
{
register uint32_t result;
asm volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
void *_sbrk_r(struct _reent *r, ptrdiff_t incr)
{
extern char end; // provided by the linker script
@ -50,40 +57,29 @@ void *_sbrk_r(struct _reent *r, ptrdiff_t incr)
__brkval += incr;
return ret;
return (void*)-1;
}
ssize_t _read(int fd, void *ptr, size_t len)
{
(void) fd;
while (!usb_rx_buf.len);
//while (!usb_rx_buf.len);
if (len > usb_rx_buf.len)
len = usb_rx_buf.len;
//if (len > usb_rx_buf.len)
// len = usb_rx_buf.len;
char *c = (char *) ptr;
for (uint16_t i = 0; i < len; i++)
rb_getc(&usb_rx_buf, c++);
for (uint16_t i = 0; i < len; i++){}
//rb_getc(&usb_rx_buf, c++);
return len;
}
int _write(int fd, const char *ptr, int len)
int _write(int file, char *ptr, int len)
{
char *c = (char *) ptr;
(void) fd;
int sent = 0;
while (len--) {
// send a queued byte - copy to usb stack buffer
APP_Rx_Buffer[APP_Rx_ptr_in++] = *c;
c++;
// To avoid buffer overflow
if (APP_Rx_ptr_in >= APP_RX_DATA_SIZE) {
APP_Rx_ptr_in = 0;
}
sent++;
if (file == STDOUT_FILENO || file == STDERR_FILENO) {
return cdcacm_tx(ptr,len);
}
return sent;
errno = EIO;
return -1;
}

View File

@ -1,193 +1,152 @@
/*
*****************************************************************************
**
** File : stm32_flash.ld
**
** Abstract : Linker script for STM32F407VG Device with
** 1024KByte FLASH, 192KByte RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Environment : Atollic TrueSTUDIO(R)
**
** Distribution: The file is distributed “as is,” without any warranty
** of any kind.
**
** (c)Copyright Atollic AB.
** You may use this file as-is or modify it according to the needs of your
** project. Distribution of this file (unmodified or modified) is not
** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
** rights to distribute the assembled, compiled & linked contents of this
** file as part of an application binary file, provided that it is built
** using the Atollic TrueSTUDIO(R) toolchain.
**
*****************************************************************************
*/
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Linker script for ST STM32F4DISCOVERY (STM32F407VG, 1024K flash, 128K RAM). */
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of 128K RAM on AHB bus*/
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
/* flash layout: 4*16+1*64+7*128=1024 */
/* Define memory regions. */
MEMORY
{
BOOT (rx) : ORIGIN = 0x08000000, LENGTH = 32K/* sector 0-1 */
PARAM0 (rx) : ORIGIN = 0x08008000, LENGTH = 16K/* sector 2 */
PARAM1 (rx) : ORIGIN = 0x0800C000, LENGTH = 16K/* sector 3 */
FLASH (rx) : ORIGIN = 0x08010000, LENGTH = 960K/* sector 4-11 */
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64k
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K/*SRAM1*/
RAM2(xrw) : ORIGIN = 0x2001C000, LENGTH = 16K/*SRAM2*/
BKP(xrw) : ORIGIN = 0x40024000, LENGTH = 4K/*backup bkp sram*/
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 960K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* Define output sections */
/* Include the common ld script. */
/*INCLUDE libopencm3_stm32f4.ld*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* Generic linker script for STM32 targets using libopencm3. */
/* Memory regions must be defined in the ld script which includes this one. */
/* Enforce emmition of the vector table. */
EXTERN (vector_table)
/* Define the entry point of the output file. */
ENTRY(reset_handler)
/* Define sections. */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
.text : {
*(.vectors) /* Vector table */
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
} >rom
/* version info needs to have a section, so the bootloader and python script can find it */
.version_info :
{
. = ALIGN(4);
KEEP(*(.version_info))
. = ALIGN(4);
} >rom
/* version info needs to have a section, so the bootloader and python script can find it */
.version_info :
{
. = ALIGN(4);
KEEP(*(.version_info))
. = ALIGN(4);
} >FLASH
.hv_firmware :
{
. = ALIGN(4);
KEEP(*(.hv_firmware))
. = ALIGN(4);
} >rom
.hv_firmware :
{
. = ALIGN(4);
KEEP(*(.hv_firmware))
. = ALIGN(4);
} >FLASH
/* C++ Static constructors/destructors, also used for __attribute__
* ((constructor)) and the likes */
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
_exit = .;
} >FLASH
.data : {
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
_edata = .;
} >ram AT >rom
_data_loadaddr = LOADADDR(.data);
.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/* MEMORY_bank1 section, code must be located here explicitly */
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
. = ALIGN(4);
end = .;
}
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));