mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-09 23:08:12 +00:00
Merge remote-tracking branch 'refs/remotes/pascallanger/master' into benlye-multi-new
This commit is contained in:
commit
7d5dabde82
64
BootLoaders/Boards/stm32/boards.txt
Normal file
64
BootLoaders/Boards/stm32/boards.txt
Normal file
@ -0,0 +1,64 @@
|
||||
# See: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
# See: http://code.google.com/p/arduino/wiki/Platforms
|
||||
|
||||
##############################################################
|
||||
|
||||
menu.upload_method=Upload method
|
||||
menu.bootloader=Bootloader
|
||||
|
||||
##############################################################
|
||||
## Multi 4-in-1 STM32
|
||||
## --------------------------------------------------
|
||||
multistm32f103c.name=Multi 4-in-1 (STM32F103CB)
|
||||
|
||||
multistm32f103c.vid.0=0x1EAF
|
||||
multistm32f103c.pid.0=0x0004
|
||||
multistm32f103c.build.variant=generic_stm32f103c
|
||||
multistm32f103c.build.vect=VECT_TAB_ADDR=0x8000000
|
||||
multistm32f103c.build.core=maple
|
||||
multistm32f103c.build.board=MULTI_STM32_FLASH_FROM_TX
|
||||
multistm32f103c.upload.use_1200bps_touch=false
|
||||
multistm32f103c.upload.file_type=bin
|
||||
multistm32f103c.upload.auto_reset=true
|
||||
multistm32f103c.upload.tool=maple_upload
|
||||
multistm32f103c.upload.protocol=maple_dfu
|
||||
|
||||
multistm32f103c.build.cpu_flags=-DMCU_STM32F103CB
|
||||
multistm32f103c.build.ldscript=ld/jtag.ld
|
||||
multistm32f103c.upload.maximum_size=131072
|
||||
multistm32f103c.upload.maximum_data_size=20480
|
||||
|
||||
multistm32f103c.build.f_cpu=72000000L
|
||||
multistm32f103c.build.flags.optimize=-Os
|
||||
multistm32f103c.build.flags.ldspecs=
|
||||
|
||||
multistm32f103c.bootloader.tool=serial_upload
|
||||
|
||||
#---------------------------- UPLOAD METHODS ---------------------------
|
||||
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod=Flash from Tx
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.upload.tool=tx_upload
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.build.vect=VECT_TAB_ADDR=0x8002000
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.build.ldscript=ld/bootloader_20.ld
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.build.board=MULTI_STM32_FLASH_FROM_TX
|
||||
multistm32f103c.menu.upload_method.TxFlashMethod.bootloader.file=Multi4in1/StmMultiBoot.bin
|
||||
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod=Upload via USB
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20.ld
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.build.board=MULTI_STM32_NO_BOOT
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.upload.altID=2
|
||||
multistm32f103c.menu.upload_method.DFUUploadMethod.bootloader.file=Multi4in1/StmMultiUSB.bin
|
||||
|
||||
multistm32f103c.menu.upload_method.serialMethod=Upload via Serial (FTDI)
|
||||
multistm32f103c.menu.upload_method.serialMethod.upload.protocol=maple_serial
|
||||
multistm32f103c.menu.upload_method.serialMethod.upload.tool=serial_upload
|
||||
multistm32f103c.menu.upload_method.serialMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG
|
||||
multistm32f103c.menu.upload_method.serialMethod.build.board=MULTI_STM32_NO_BOOT
|
||||
|
||||
##############################################################
|
BIN
BootLoaders/Boards/stm32/bootloaders/Multi4in1/StmMultiBoot.bin
Normal file
BIN
BootLoaders/Boards/stm32/bootloaders/Multi4in1/StmMultiBoot.bin
Normal file
Binary file not shown.
BIN
BootLoaders/Boards/stm32/bootloaders/Multi4in1/StmMultiUSB.bin
Normal file
BIN
BootLoaders/Boards/stm32/bootloaders/Multi4in1/StmMultiUSB.bin
Normal file
Binary file not shown.
44
BootLoaders/Boards/stm32/cores/maple/Arduino.h
Normal file
44
BootLoaders/Boards/stm32/cores/maple/Arduino.h
Normal file
@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _WIRISH_WPROGRAM_H_
|
||||
#define _WIRISH_WPROGRAM_H_
|
||||
|
||||
#include "wirish.h"
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif // __cplusplus
|
||||
void yield(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
#endif
|
45
BootLoaders/Boards/stm32/cores/maple/Client.h
Normal file
45
BootLoaders/Boards/stm32/cores/maple/Client.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Client.h - Base class that provides Client
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef client_h
|
||||
#define client_h
|
||||
#include "Print.h"
|
||||
#include "Stream.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
class Client : public Stream {
|
||||
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||
virtual int connect(const char *host, uint16_t port) =0;
|
||||
virtual size_t write(uint8_t) =0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
200
BootLoaders/Boards/stm32/cores/maple/HardwareSerial.cpp
Normal file
200
BootLoaders/Boards/stm32/cores/maple/HardwareSerial.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/HardwareSerial.cpp
|
||||
* @brief Wirish serial port implementation.
|
||||
*/
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/timer.h>
|
||||
#include <libmaple/usart.h>
|
||||
|
||||
#if 0
|
||||
|
||||
#define DEFINE_HWSERIAL(name, n) \
|
||||
HardwareSerial name(USART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN)
|
||||
|
||||
#define DEFINE_HWSERIAL_UART(name, n) \
|
||||
HardwareSerial name(UART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN)
|
||||
|
||||
#ifdef SERIAL_USB
|
||||
#if BOARD_HAVE_USART1
|
||||
DEFINE_HWSERIAL(Serial1, 1);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART2
|
||||
DEFINE_HWSERIAL(Serial2, 2);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART3
|
||||
DEFINE_HWSERIAL(Serial3, 3);
|
||||
#endif
|
||||
#if BOARD_HAVE_UART4
|
||||
DEFINE_HWSERIAL_UART(Serial4, 4);
|
||||
#endif
|
||||
#if BOARD_HAVE_UART5
|
||||
DEFINE_HWSERIAL_UART(Serial5, 5);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART6
|
||||
DEFINE_HWSERIAL_UART(Serial6, 6);
|
||||
#endif
|
||||
#else
|
||||
#if BOARD_HAVE_USART1
|
||||
DEFINE_HWSERIAL(Serial, 1);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART2
|
||||
DEFINE_HWSERIAL(Serial1, 2);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART3
|
||||
DEFINE_HWSERIAL(Serial2, 3);
|
||||
#endif
|
||||
#if BOARD_HAVE_UART4
|
||||
DEFINE_HWSERIAL_UART(Serial3, 4);
|
||||
#endif
|
||||
#if BOARD_HAVE_UART5
|
||||
DEFINE_HWSERIAL_UART(Serial4, 5);
|
||||
#endif
|
||||
#if BOARD_HAVE_USART6
|
||||
DEFINE_HWSERIAL_UART(Serial5, 6);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
HardwareSerial::HardwareSerial(usart_dev *usart_device,
|
||||
uint8 tx_pin,
|
||||
uint8 rx_pin) {
|
||||
this->usart_device = usart_device;
|
||||
this->tx_pin = tx_pin;
|
||||
this->rx_pin = rx_pin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up/tear down
|
||||
*/
|
||||
|
||||
#if STM32_MCU_SERIES == STM32_SERIES_F1
|
||||
/* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict
|
||||
* on this GPIO bit. */
|
||||
static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) {
|
||||
if (dev != NULL) {
|
||||
timer_set_mode(dev, ch, TIMER_DISABLED);
|
||||
}
|
||||
}
|
||||
#elif (STM32_MCU_SERIES == STM32_SERIES_F2) || \
|
||||
(STM32_MCU_SERIES == STM32_SERIES_F4)
|
||||
#define disable_timer_if_necessary(dev, ch) ((void)0)
|
||||
#else
|
||||
#warning "Unsupported STM32 series; timer conflicts are possible"
|
||||
#endif
|
||||
|
||||
void HardwareSerial::begin(uint32 baud)
|
||||
{
|
||||
begin(baud,SERIAL_8N1);
|
||||
}
|
||||
/*
|
||||
* Roger Clark.
|
||||
* Note. The config parameter is not currently used. This is a work in progress.
|
||||
* Code needs to be written to set the config of the hardware serial control register in question.
|
||||
*
|
||||
*/
|
||||
|
||||
void HardwareSerial::begin(uint32 baud, uint8_t config)
|
||||
{
|
||||
// ASSERT(baud <= this->usart_device->max_baud);// Roger Clark. Assert doesn't do anything useful, we may as well save the space in flash and ram etc
|
||||
|
||||
if (baud > this->usart_device->max_baud) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stm32_pin_info *txi = &PIN_MAP[this->tx_pin];
|
||||
const stm32_pin_info *rxi = &PIN_MAP[this->rx_pin];
|
||||
|
||||
disable_timer_if_necessary(txi->timer_device, txi->timer_channel);
|
||||
|
||||
usart_init(this->usart_device);
|
||||
usart_config_gpios_async(this->usart_device,
|
||||
rxi->gpio_device, rxi->gpio_bit,
|
||||
txi->gpio_device, txi->gpio_bit,
|
||||
config);
|
||||
usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud);
|
||||
usart_enable(this->usart_device);
|
||||
}
|
||||
|
||||
void HardwareSerial::end(void) {
|
||||
usart_disable(this->usart_device);
|
||||
}
|
||||
|
||||
/*
|
||||
* I/O
|
||||
*/
|
||||
|
||||
int HardwareSerial::read(void) {
|
||||
if(usart_data_available(usart_device) > 0) {
|
||||
return usart_getc(usart_device);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void) {
|
||||
return usart_data_available(this->usart_device);
|
||||
}
|
||||
|
||||
/* Roger Clark. Added function missing from LibMaple code */
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
return usart_peek(this->usart_device);
|
||||
}
|
||||
|
||||
int HardwareSerial::availableForWrite(void)
|
||||
{
|
||||
/* Roger Clark.
|
||||
* Currently there isn't an output ring buffer, chars are sent straight to the hardware.
|
||||
* so just return 1, meaning that 1 char can be written
|
||||
* This will be slower than a ring buffer implementation, but it should at least work !
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(unsigned char ch) {
|
||||
|
||||
usart_putc(this->usart_device, ch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* edogaldo: Waits for the transmission of outgoing serial data to complete (Arduino 1.0 api specs) */
|
||||
void HardwareSerial::flush(void) {
|
||||
while(!rb_is_empty(this->usart_device->wb)); // wait for TX buffer empty
|
||||
while(!((this->usart_device->regs->SR) & (1<<USART_SR_TC_BIT))); // wait for TC (Transmission Complete) flag set
|
||||
}
|
224
BootLoaders/Boards/stm32/cores/maple/HardwareSerial.h
Normal file
224
BootLoaders/Boards/stm32/cores/maple/HardwareSerial.h
Normal file
@ -0,0 +1,224 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/include/wirish/HardwareSerial.h
|
||||
* @brief Wirish serial port interface.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_HARDWARESERIAL_H_
|
||||
#define _WIRISH_HARDWARESERIAL_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
|
||||
#include "Print.h"
|
||||
#include "boards.h"
|
||||
#include "Stream.h"
|
||||
/*
|
||||
* IMPORTANT:
|
||||
*
|
||||
* This class documented "by hand" (i.e., not using Doxygen) in the
|
||||
* leaflabs-docs/ repository.
|
||||
*
|
||||
* If you alter the public HardwareSerial interface, you MUST update
|
||||
* the documentation accordingly.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Define constants and variables for buffering incoming serial data. We're
|
||||
// using a ring buffer (I think), in which head is the index of the location
|
||||
// to which to write the next incoming character and tail is the index of the
|
||||
// location from which to read.
|
||||
#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE))
|
||||
#if (RAMEND < 1000)
|
||||
#define SERIAL_TX_BUFFER_SIZE 16
|
||||
#define SERIAL_RX_BUFFER_SIZE 16
|
||||
#else
|
||||
#define SERIAL_TX_BUFFER_SIZE 64
|
||||
#define SERIAL_RX_BUFFER_SIZE 64
|
||||
#endif
|
||||
#endif
|
||||
#if (SERIAL_TX_BUFFER_SIZE>256)
|
||||
typedef uint16_t tx_buffer_index_t;
|
||||
#else
|
||||
typedef uint8_t tx_buffer_index_t;
|
||||
#endif
|
||||
#if (SERIAL_RX_BUFFER_SIZE>256)
|
||||
typedef uint16_t rx_buffer_index_t;
|
||||
#else
|
||||
typedef uint8_t rx_buffer_index_t;
|
||||
#endif
|
||||
|
||||
struct usart_dev;
|
||||
|
||||
/* Roger Clark
|
||||
*
|
||||
* Added config defines from AVR
|
||||
* Note. The values will need to be changed to match STM32 USART config register values, these are just place holders.
|
||||
*/
|
||||
// Define config for Serial.begin(baud, config);
|
||||
// Note. STM32 doesn't support as many different Serial modes as AVR or SAM cores.
|
||||
// The word legth bit M must be set when using parity bit.
|
||||
|
||||
#define SERIAL_8N1 0B00000000
|
||||
#define SERIAL_8N2 0B00100000
|
||||
#define SERIAL_9N1 0B00001000
|
||||
#define SERIAL_9N2 0B00101000
|
||||
|
||||
#define SERIAL_8E1 0B00001010
|
||||
#define SERIAL_8E2 0B00101010
|
||||
/* not supported:
|
||||
#define SERIAL_9E1 0B00001010
|
||||
#define SERIAL_9E2 0B00101010
|
||||
*/
|
||||
#define SERIAL_8O1 0B00001011
|
||||
#define SERIAL_8O2 0B00101011
|
||||
/* not supported:
|
||||
#define SERIAL_9O1 0B00001011
|
||||
#define SERIAL_9O2 0B00101011
|
||||
*/
|
||||
|
||||
/* Roger Clark
|
||||
* Moved macros from hardwareSerial.cpp
|
||||
*/
|
||||
|
||||
#define DEFINE_HWSERIAL(name, n) \
|
||||
HardwareSerial name(USART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN)
|
||||
|
||||
#define DEFINE_HWSERIAL_UART(name, n) \
|
||||
HardwareSerial name(UART##n, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN)
|
||||
|
||||
|
||||
/* Roger clark. Changed class inheritance from Print to Stream.
|
||||
* Also added new functions for peek() and availableForWrite()
|
||||
* Note. AvailableForWrite is only a stub function in the cpp
|
||||
*/
|
||||
class HardwareSerial : public Stream {
|
||||
|
||||
public:
|
||||
HardwareSerial(struct usart_dev *usart_device,
|
||||
uint8 tx_pin,
|
||||
uint8 rx_pin);
|
||||
|
||||
/* Set up/tear down */
|
||||
void begin(uint32 baud);
|
||||
void begin(uint32 baud,uint8_t config);
|
||||
void end();
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
int availableForWrite(void);
|
||||
virtual void flush(void);
|
||||
virtual size_t write(uint8_t);
|
||||
inline size_t write(unsigned long n) { return write((uint8_t)n); }
|
||||
inline size_t write(long n) { return write((uint8_t)n); }
|
||||
inline size_t write(unsigned int n) { return write((uint8_t)n); }
|
||||
inline size_t write(int n) { return write((uint8_t)n); }
|
||||
using Print::write;
|
||||
|
||||
/* Pin accessors */
|
||||
int txPin(void) { return this->tx_pin; }
|
||||
int rxPin(void) { return this->rx_pin; }
|
||||
|
||||
operator bool() { return true; }
|
||||
|
||||
/* Escape hatch into libmaple */
|
||||
/* FIXME [0.0.13] documentation */
|
||||
struct usart_dev* c_dev(void) { return this->usart_device; }
|
||||
private:
|
||||
struct usart_dev *usart_device;
|
||||
uint8 tx_pin;
|
||||
uint8 rx_pin;
|
||||
protected:
|
||||
#if 0
|
||||
volatile uint8_t * const _ubrrh;
|
||||
volatile uint8_t * const _ubrrl;
|
||||
volatile uint8_t * const _ucsra;
|
||||
volatile uint8_t * const _ucsrb;
|
||||
volatile uint8_t * const _ucsrc;
|
||||
volatile uint8_t * const _udr;
|
||||
// Has any byte been written to the UART since begin()
|
||||
bool _written;
|
||||
|
||||
volatile rx_buffer_index_t _rx_buffer_head;
|
||||
volatile rx_buffer_index_t _rx_buffer_tail;
|
||||
volatile tx_buffer_index_t _tx_buffer_head;
|
||||
volatile tx_buffer_index_t _tx_buffer_tail;
|
||||
// Don't put any members after these buffers, since only the first
|
||||
// 32 bytes of this struct can be accessed quickly using the ldd
|
||||
// instruction.
|
||||
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
|
||||
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef SERIAL_USB
|
||||
#if BOARD_HAVE_USART1
|
||||
extern HardwareSerial Serial1;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART2
|
||||
extern HardwareSerial Serial2;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART3
|
||||
extern HardwareSerial Serial3;
|
||||
#endif
|
||||
#if BOARD_HAVE_UART4
|
||||
extern HardwareSerial Serial4;
|
||||
#endif
|
||||
#if BOARD_HAVE_UART5
|
||||
extern HardwareSerial Serial5;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART6
|
||||
extern HardwareSerial Serial6;
|
||||
#endif
|
||||
#else
|
||||
#if BOARD_HAVE_USART1
|
||||
extern HardwareSerial Serial;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART2
|
||||
extern HardwareSerial Serial1;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART3
|
||||
extern HardwareSerial Serial2;
|
||||
#endif
|
||||
#if BOARD_HAVE_UART4
|
||||
extern HardwareSerial Serial3;
|
||||
#endif
|
||||
#if BOARD_HAVE_UART5
|
||||
extern HardwareSerial Serial4;
|
||||
#endif
|
||||
#if BOARD_HAVE_USART6
|
||||
extern HardwareSerial Serial5;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
192
BootLoaders/Boards/stm32/cores/maple/HardwareTimer.cpp
Normal file
192
BootLoaders/Boards/stm32/cores/maple/HardwareTimer.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Bryan Newbold.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "HardwareTimer.h"
|
||||
|
||||
#include <libmaple/rcc.h>
|
||||
#include "ext_interrupts.h" // for noInterrupts(), interrupts()
|
||||
#include "wirish_math.h"
|
||||
#include <board/board.h> // for CYCLES_PER_MICROSECOND
|
||||
|
||||
// TODO [0.1.0] Remove deprecated pieces
|
||||
|
||||
/*
|
||||
* Evil hack to infer this->dev from timerNum in the HardwareTimer
|
||||
* constructor. See:
|
||||
*
|
||||
* http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
|
||||
* http://yosefk.com/c++fqa/function.html#fqa-33.2
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
static timer_dev **this_devp;
|
||||
static rcc_clk_id this_id;
|
||||
static void set_this_dev(timer_dev *dev) {
|
||||
if (dev->clk_id == this_id) {
|
||||
*this_devp = dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* HardwareTimer routines
|
||||
*/
|
||||
|
||||
HardwareTimer::HardwareTimer(uint8 timerNum) {
|
||||
rcc_clk_id timerID = (rcc_clk_id)(RCC_TIMER1 + (timerNum - 1));
|
||||
this->dev = NULL;
|
||||
noInterrupts(); // Hack to ensure we're the only ones using
|
||||
// set_this_dev() and friends. TODO: use a lock.
|
||||
this_id = timerID;
|
||||
this_devp = &this->dev;
|
||||
timer_foreach(set_this_dev);
|
||||
interrupts();
|
||||
ASSERT(this->dev != NULL);
|
||||
}
|
||||
|
||||
void HardwareTimer::pause(void) {
|
||||
timer_pause(this->dev);
|
||||
}
|
||||
|
||||
void HardwareTimer::resume(void) {
|
||||
timer_resume(this->dev);
|
||||
}
|
||||
|
||||
uint32 HardwareTimer::getPrescaleFactor(void) {
|
||||
return timer_get_prescaler(this->dev) + 1;
|
||||
}
|
||||
|
||||
void HardwareTimer::setPrescaleFactor(uint32 factor) {
|
||||
timer_set_prescaler(this->dev, (uint16)(factor - 1));
|
||||
}
|
||||
|
||||
uint16 HardwareTimer::getOverflow() {
|
||||
return timer_get_reload(this->dev);
|
||||
}
|
||||
|
||||
void HardwareTimer::setOverflow(uint16 val) {
|
||||
timer_set_reload(this->dev, val);
|
||||
}
|
||||
|
||||
uint16 HardwareTimer::getCount(void) {
|
||||
return timer_get_count(this->dev);
|
||||
}
|
||||
|
||||
void HardwareTimer::setCount(uint16 val) {
|
||||
uint16 ovf = this->getOverflow();
|
||||
timer_set_count(this->dev, min(val, ovf));
|
||||
}
|
||||
|
||||
#define MAX_RELOAD ((1 << 16) - 1)
|
||||
uint16 HardwareTimer::setPeriod(uint32 microseconds) {
|
||||
// Not the best way to handle this edge case?
|
||||
if (!microseconds) {
|
||||
this->setPrescaleFactor(1);
|
||||
this->setOverflow(1);
|
||||
return this->getOverflow();
|
||||
}
|
||||
|
||||
uint32 period_cyc = microseconds * CYCLES_PER_MICROSECOND;
|
||||
uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1);
|
||||
uint16 overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler);
|
||||
this->setPrescaleFactor(prescaler);
|
||||
this->setOverflow(overflow);
|
||||
return overflow;
|
||||
}
|
||||
|
||||
void HardwareTimer::setMode(int channel, timer_mode mode) {
|
||||
timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode);
|
||||
}
|
||||
|
||||
uint16 HardwareTimer::getCompare(int channel) {
|
||||
return timer_get_compare(this->dev, (uint8)channel);
|
||||
}
|
||||
|
||||
void HardwareTimer::setCompare(int channel, uint16 val) {
|
||||
uint16 ovf = this->getOverflow();
|
||||
timer_set_compare(this->dev, (uint8)channel, min(val, ovf));
|
||||
}
|
||||
|
||||
void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) {
|
||||
timer_attach_interrupt(this->dev, (uint8)channel, handler);
|
||||
}
|
||||
|
||||
void HardwareTimer::detachInterrupt(int channel) {
|
||||
timer_detach_interrupt(this->dev, (uint8)channel);
|
||||
}
|
||||
|
||||
|
||||
void HardwareTimer::enableDMA(int channel) {
|
||||
timer_dma_enable_req(this->dev, (uint8)channel);
|
||||
}
|
||||
|
||||
void HardwareTimer::disableDMA(int channel) {
|
||||
timer_dma_disable_req(this->dev, (uint8)channel);
|
||||
}
|
||||
|
||||
void HardwareTimer::refresh(void) {
|
||||
timer_generate_update(this->dev);
|
||||
}
|
||||
|
||||
void HardwareTimer::setMasterModeTrGo(uint32_t mode) {
|
||||
this->dev->regs.bas->CR2 &= ~TIMER_CR2_MMS;
|
||||
this->dev->regs.bas->CR2 |= mode;
|
||||
}
|
||||
|
||||
/* CARLOS Changes to add encoder mode.*/
|
||||
|
||||
//direction of movement. (to be better described).
|
||||
uint8 HardwareTimer::getDirection(){
|
||||
return get_direction(this->dev);
|
||||
}
|
||||
|
||||
//set if the encoder will count edges on one, which or both channels.
|
||||
void HardwareTimer::setEdgeCounting(uint32 counting) {
|
||||
(dev->regs).gen->SMCR = counting;//TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on
|
||||
|
||||
}
|
||||
|
||||
uint8 HardwareTimer::getEdgeCounting() {
|
||||
return (dev->regs).gen->SMCR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//set the polarity of counting... not sure how interesting this is..
|
||||
void HardwareTimer::setPolarity(){}
|
||||
|
||||
/* -- Deprecated predefined instances -------------------------------------- */
|
||||
|
||||
HardwareTimer Timer1(1);
|
||||
HardwareTimer Timer2(2);
|
||||
HardwareTimer Timer3(3);
|
||||
HardwareTimer Timer4(4);
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
HardwareTimer Timer5(5);
|
||||
HardwareTimer Timer6(6);
|
||||
HardwareTimer Timer7(7);
|
||||
HardwareTimer Timer8(8);
|
||||
#endif
|
381
BootLoaders/Boards/stm32/cores/maple/HardwareTimer.h
Normal file
381
BootLoaders/Boards/stm32/cores/maple/HardwareTimer.h
Normal file
@ -0,0 +1,381 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Bryan Newbold.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Wirish timer class.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_HARDWARETIMER_H_
|
||||
#define _WIRISH_HARDWARETIMER_H_
|
||||
|
||||
// TODO [0.1.0] Remove deprecated pieces, pick a better API
|
||||
|
||||
#include <libmaple/timer.h>
|
||||
|
||||
/** Timer mode. */
|
||||
typedef timer_mode TimerMode;
|
||||
|
||||
//CARLOS
|
||||
//defines for the ENCODER mode.
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interface to one of the 16-bit timer peripherals.
|
||||
*/
|
||||
class HardwareTimer {
|
||||
private:
|
||||
timer_dev *dev;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new HardwareTimer instance.
|
||||
* @param timerNum number of the timer to control.
|
||||
*/
|
||||
HardwareTimer(uint8 timerNum);
|
||||
|
||||
/**
|
||||
* @brief Stop the counter, without affecting its configuration.
|
||||
*
|
||||
* @see HardwareTimer::resume()
|
||||
*/
|
||||
void pause(void);
|
||||
|
||||
/**
|
||||
* @brief Resume a paused timer, without affecting its configuration.
|
||||
*
|
||||
* The timer will resume counting and firing interrupts as
|
||||
* appropriate.
|
||||
*
|
||||
* Note that there is some function call overhead associated with
|
||||
* using this method, so using it in concert with
|
||||
* HardwareTimer::pause() is not a robust way to align multiple
|
||||
* timers to the same count value.
|
||||
*
|
||||
* @see HardwareTimer::pause()
|
||||
*/
|
||||
void resume(void);
|
||||
|
||||
/**
|
||||
* @brief Get the timer's prescale factor.
|
||||
* @return Timer prescaler, from 1 to 65,536.
|
||||
* @see HardwareTimer::setPrescaleFactor()
|
||||
*/
|
||||
uint32 getPrescaleFactor();
|
||||
|
||||
/**
|
||||
* @brief Set the timer's prescale factor.
|
||||
*
|
||||
* The new value won't take effect until the next time the counter
|
||||
* overflows. You can force the counter to reset using
|
||||
* HardwareTimer::refresh().
|
||||
*
|
||||
* @param factor The new prescale value to set, from 1 to 65,536.
|
||||
* @see HardwareTimer::refresh()
|
||||
*/
|
||||
void setPrescaleFactor(uint32 factor);
|
||||
|
||||
/**
|
||||
* @brief Get the timer overflow value.
|
||||
* @see HardwareTimer::setOverflow()
|
||||
*/
|
||||
uint16 getOverflow();
|
||||
|
||||
/**
|
||||
* @brief Set the timer overflow (or "reload") value.
|
||||
*
|
||||
* The new value won't take effect until the next time the counter
|
||||
* overflows. You can force the counter to reset using
|
||||
* HardwareTimer::refresh().
|
||||
*
|
||||
* @param val The new overflow value to set
|
||||
* @see HardwareTimer::refresh()
|
||||
*/
|
||||
void setOverflow(uint16 val);
|
||||
|
||||
/**
|
||||
* @brief Get the current timer count.
|
||||
*
|
||||
* @return The timer's current count value
|
||||
*/
|
||||
uint16 getCount(void);
|
||||
|
||||
/**
|
||||
* @brief Set the current timer count.
|
||||
*
|
||||
* @param val The new count value to set. If this value exceeds
|
||||
* the timer's overflow value, it is truncated to the
|
||||
* overflow value.
|
||||
*/
|
||||
void setCount(uint16 val);
|
||||
|
||||
/**
|
||||
* @brief Set the timer's period in microseconds.
|
||||
*
|
||||
* Configures the prescaler and overflow values to generate a timer
|
||||
* reload with a period as close to the given number of
|
||||
* microseconds as possible.
|
||||
*
|
||||
* @param microseconds The desired period of the timer. This must be
|
||||
* greater than zero.
|
||||
* @return The new overflow value.
|
||||
*/
|
||||
uint16 setPeriod(uint32 microseconds);
|
||||
|
||||
/**
|
||||
* @brief Configure a timer channel's mode.
|
||||
* @param channel Timer channel, from 1 to 4
|
||||
* @param mode Mode to set
|
||||
*/
|
||||
void setMode(int channel, timer_mode mode);
|
||||
|
||||
/**
|
||||
* @brief Get the compare value for the given channel.
|
||||
* @see HardwareTimer::setCompare()
|
||||
*/
|
||||
uint16 getCompare(int channel);
|
||||
|
||||
/**
|
||||
* @brief Set the compare value for the given channel.
|
||||
*
|
||||
* @param channel the channel whose compare to set, from 1 to 4.
|
||||
* @param compare The compare value to set. If greater than this
|
||||
* timer's overflow value, it will be truncated to
|
||||
* the overflow value.
|
||||
*
|
||||
* @see timer_mode
|
||||
* @see HardwareTimer::setMode()
|
||||
* @see HardwareTimer::attachInterrupt()
|
||||
*/
|
||||
void setCompare(int channel, uint16 compare);
|
||||
|
||||
/**
|
||||
* @brief Attach an interrupt handler to the given channel.
|
||||
*
|
||||
* This interrupt handler will be called when the timer's counter
|
||||
* reaches the given channel compare value.
|
||||
*
|
||||
* @param channel the channel to attach the ISR to, from 1 to 4.
|
||||
* @param handler The ISR to attach to the given channel.
|
||||
* @see voidFuncPtr
|
||||
*/
|
||||
void attachInterrupt(int channel, voidFuncPtr handler);
|
||||
|
||||
/**
|
||||
* @brief Remove the interrupt handler attached to the given
|
||||
* channel, if any.
|
||||
*
|
||||
* The handler will no longer be called by this timer.
|
||||
*
|
||||
* @param channel the channel whose interrupt to detach, from 1 to 4.
|
||||
* @see HardwareTimer::attachInterrupt()
|
||||
*/
|
||||
void detachInterrupt(int channel);
|
||||
|
||||
/**
|
||||
* @brief Reset the counter, and update the prescaler and overflow
|
||||
* values.
|
||||
*
|
||||
* This will reset the counter to 0 in upcounting mode (the
|
||||
* default). It will also update the timer's prescaler and
|
||||
* overflow, if you have set them up to be changed using
|
||||
* HardwareTimer::setPrescaleFactor() or
|
||||
* HardwareTimer::setOverflow().
|
||||
*
|
||||
* @see HardwareTimer::setPrescaleFactor()
|
||||
* @see HardwareTimer::setOverflow()
|
||||
*/
|
||||
void refresh(void);
|
||||
|
||||
// SYFRE
|
||||
/**
|
||||
* @brief Set the Master mode TRGO signal
|
||||
* These bits allow to select the information to be sent in master mode to slave timers for
|
||||
* synchronization (TRGO).
|
||||
* mode:
|
||||
* TIMER_CR2_MMS_RESET
|
||||
* TIMER_CR2_MMS_ENABLE
|
||||
* TIMER_CR2_MMS_UPDATE
|
||||
* TIMER_CR2_MMS_COMPARE_PULSE
|
||||
* TIMER_CR2_MMS_COMPARE_OC1REF
|
||||
* TIMER_CR2_MMS_COMPARE_OC2REF
|
||||
* TIMER_CR2_MMS_COMPARE_OC3REF
|
||||
* TIMER_CR2_MMS_COMPARE_OC4REF
|
||||
*/
|
||||
void setMasterModeTrGo(uint32_t mode);
|
||||
|
||||
//CARLOS.
|
||||
/*
|
||||
added these functions to make sense for the encoder mode.
|
||||
*/
|
||||
//direction of movement. (to be better described).
|
||||
uint8 getDirection();
|
||||
|
||||
//set if the encoder will count edges on one, which or both channels.
|
||||
void setEdgeCounting(uint32 counting);
|
||||
uint8 getEdgeCounting(); //not sure if needed.
|
||||
|
||||
//set the polarity of counting... not sure how interesting this is..
|
||||
void setPolarity();
|
||||
|
||||
//add the filtering definition for the input channel.
|
||||
|
||||
|
||||
/* Escape hatch */
|
||||
|
||||
/**
|
||||
* @brief Enable/disable DMA request for the input channel.
|
||||
*/
|
||||
void enableDMA(int channel);
|
||||
void disableDMA(int channel);
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the underlying libmaple timer_dev for
|
||||
* this HardwareTimer instance.
|
||||
*/
|
||||
timer_dev* c_dev(void) { return this->dev; }
|
||||
|
||||
/* -- The rest of this file is deprecated. --------------------------------- */
|
||||
|
||||
/** @brief Deprecated; use setMode(channel, mode) instead. */
|
||||
void setChannelMode(int channel, timer_mode mode) {
|
||||
setMode(channel, mode);
|
||||
}
|
||||
|
||||
/** @brief Deprecated; use setMode(TIMER_CH1, mode) instead. */
|
||||
void setChannel1Mode(timer_mode mode) { setMode(TIMER_CH1, mode); }
|
||||
|
||||
/** @brief Deprecated; use setMode(TIMER_CH2, mode) instead. */
|
||||
void setChannel2Mode(timer_mode mode) { setMode(TIMER_CH2, mode); }
|
||||
|
||||
/** @brief Deprecated; use setMode(TIMER_CH3, mode) instead. */
|
||||
void setChannel3Mode(timer_mode mode) { setMode(TIMER_CH3, mode); }
|
||||
|
||||
/** @brief Deprecated; use setMode(TIMER_CH4, mode) instead. */
|
||||
void setChannel4Mode(timer_mode mode) { setMode(TIMER_CH4, mode); }
|
||||
|
||||
/** @brief Deprecated; use return getCompare(TIMER_CH1) instead. */
|
||||
uint16 getCompare1() { return getCompare(TIMER_CH1); }
|
||||
|
||||
/** @brief Deprecated; use return getCompare(TIMER_CH2) instead. */
|
||||
uint16 getCompare2() { return getCompare(TIMER_CH2); }
|
||||
|
||||
/** @brief Deprecated; use return getCompare(TIMER_CH3) instead. */
|
||||
uint16 getCompare3() { return getCompare(TIMER_CH3); }
|
||||
|
||||
/** @brief Deprecated; use return getCompare(TIMER_CH4) instead. */
|
||||
uint16 getCompare4() { return getCompare(TIMER_CH4); }
|
||||
|
||||
/** @brief Deprecated; use setCompare(TIMER_CH1, compare) instead. */
|
||||
void setCompare1(uint16 compare) { setCompare(TIMER_CH1, compare); }
|
||||
|
||||
/** @brief Deprecated; use setCompare(TIMER_CH2, compare) instead. */
|
||||
void setCompare2(uint16 compare) { setCompare(TIMER_CH2, compare); }
|
||||
|
||||
/** @brief Deprecated; use setCompare(TIMER_CH3, compare) instead. */
|
||||
void setCompare3(uint16 compare) { setCompare(TIMER_CH3, compare); }
|
||||
|
||||
/** @brief Deprecated; use setCompare(TIMER_CH4, compare) instead. */
|
||||
void setCompare4(uint16 compare) { setCompare(TIMER_CH4, compare); }
|
||||
|
||||
/** @brief Deprecated; use attachInterrupt(TIMER_CH1, handler) instead. */
|
||||
void attachCompare1Interrupt(voidFuncPtr handler) {
|
||||
attachInterrupt(TIMER_CH1, handler);
|
||||
}
|
||||
|
||||
/** @brief Deprecated; use attachInterrupt(TIMER_CH2, handler) instead. */
|
||||
void attachCompare2Interrupt(voidFuncPtr handler) {
|
||||
attachInterrupt(TIMER_CH2, handler);
|
||||
}
|
||||
|
||||
/** @brief Deprecated; use attachInterrupt(TIMER_CH3, handler) instead. */
|
||||
void attachCompare3Interrupt(voidFuncPtr handler) {
|
||||
attachInterrupt(TIMER_CH3, handler);
|
||||
}
|
||||
|
||||
/** @brief Deprecated; use attachInterrupt(TIMER_CH4, handler) instead. */
|
||||
void attachCompare4Interrupt(voidFuncPtr handler) {
|
||||
attachInterrupt(TIMER_CH4, handler);
|
||||
}
|
||||
|
||||
/** @brief Deprecated; use detachInterrupt(TIMER_CH1) instead. */
|
||||
void detachCompare1Interrupt(void) { detachInterrupt(TIMER_CH1); }
|
||||
|
||||
/** @brief Deprecated; use detachInterrupt(TIMER_CH2) instead. */
|
||||
void detachCompare2Interrupt(void) { detachInterrupt(TIMER_CH2); }
|
||||
|
||||
/** @brief Deprecated; use detachInterrupt(TIMER_CH3) instead. */
|
||||
void detachCompare3Interrupt(void) { detachInterrupt(TIMER_CH3); }
|
||||
|
||||
/** @brief Deprecated; use detachInterrupt(TIMER_CH4) instead. */
|
||||
void detachCompare4Interrupt(void) { detachInterrupt(TIMER_CH4); }
|
||||
|
||||
/** @brief Deprecated; use refresh() instead. */
|
||||
void generateUpdate(void) { refresh(); }
|
||||
};
|
||||
|
||||
/** @brief Deprecated; use TIMER_OUTPUT_COMPARE instead. */
|
||||
#define TIMER_OUTPUTCOMPARE TIMER_OUTPUT_COMPARE
|
||||
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer1;
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer2;
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer3;
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer4;
|
||||
#if (STM32_MCU_SERIES == STM32_SERIES_F1) && defined(STM32_HIGH_DENSITY)
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer5;
|
||||
/**
|
||||
* @brief Deprecated.
|
||||
*
|
||||
* Pre-instantiated timer.
|
||||
*/
|
||||
extern HardwareTimer Timer8;
|
||||
#endif
|
||||
|
||||
#endif
|
129
BootLoaders/Boards/stm32/cores/maple/IPAddress.cpp
Normal file
129
BootLoaders/Boards/stm32/cores/maple/IPAddress.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
IPAddress.cpp - Base class that provides IPAddress
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#include <Print.h>
|
||||
|
||||
IPAddress::IPAddress()
|
||||
{
|
||||
_address.dword = 0;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
||||
{
|
||||
_address.bytes[0] = first_octet;
|
||||
_address.bytes[1] = second_octet;
|
||||
_address.bytes[2] = third_octet;
|
||||
_address.bytes[3] = fourth_octet;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint32_t address)
|
||||
{
|
||||
_address.dword = address;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
}
|
||||
|
||||
bool IPAddress::fromString(const char *address)
|
||||
{
|
||||
// TODO: add support for "a", "a.b", "a.b.c" formats
|
||||
|
||||
uint16_t acc = 0; // Accumulator
|
||||
uint8_t dots = 0;
|
||||
|
||||
while (*address)
|
||||
{
|
||||
char c = *address++;
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
acc = acc * 10 + (c - '0');
|
||||
if (acc > 255) {
|
||||
// Value out of [0..255] range
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (c == '.')
|
||||
{
|
||||
if (dots == 3) {
|
||||
// Too much dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[dots++] = acc;
|
||||
acc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid char
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dots != 3) {
|
||||
// Too few dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[3] = acc;
|
||||
return true;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
return *this;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(uint32_t address)
|
||||
{
|
||||
_address.dword = address;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr) const
|
||||
{
|
||||
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
|
||||
}
|
||||
|
||||
size_t IPAddress::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
for (int i =0; i < 3; i++)
|
||||
{
|
||||
n += p.print(_address.bytes[i], DEC);
|
||||
n += p.print('.');
|
||||
}
|
||||
n += p.print(_address.bytes[3], DEC);
|
||||
return n;
|
||||
}
|
||||
|
||||
String IPAddress::toString()
|
||||
{
|
||||
String str = String(_address.bytes[0]);
|
||||
str += ".";
|
||||
str += String(_address.bytes[1]);
|
||||
str += ".";
|
||||
str += String(_address.bytes[2]);
|
||||
str += ".";
|
||||
str += String(_address.bytes[3]);
|
||||
return str;
|
||||
}
|
||||
|
80
BootLoaders/Boards/stm32/cores/maple/IPAddress.h
Normal file
80
BootLoaders/Boards/stm32/cores/maple/IPAddress.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
IPAddress.h - Base class that provides IPAddress
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef IPAddress_h
|
||||
#define IPAddress_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WString.h>
|
||||
#include <Printable.h>
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
|
||||
class IPAddress : public Printable {
|
||||
private:
|
||||
union {
|
||||
uint8_t bytes[4]; // IPv4 address
|
||||
uint32_t dword;
|
||||
} _address;
|
||||
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address() { return _address.bytes; };
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
IPAddress();
|
||||
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
||||
IPAddress(uint32_t address);
|
||||
IPAddress(const uint8_t *address);
|
||||
|
||||
bool fromString(const char *address);
|
||||
bool fromString(const String &address) { return fromString(address.c_str()); }
|
||||
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint32_t() const { return _address.dword; };
|
||||
bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
|
||||
bool operator==(const uint8_t* addr) const;
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const { return _address.bytes[index]; };
|
||||
uint8_t& operator[](int index) { return _address.bytes[index]; };
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
IPAddress& operator=(const uint8_t *address);
|
||||
IPAddress& operator=(uint32_t address);
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
String toString();
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0,0,0,0);
|
||||
|
||||
|
||||
#endif
|
322
BootLoaders/Boards/stm32/cores/maple/Print.cpp
Normal file
322
BootLoaders/Boards/stm32/cores/maple/Print.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Print.cpp - Base class that provides print() and println()
|
||||
* Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* 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 2.1 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Modified 23 November 2006 by David A. Mellis
|
||||
* Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com>
|
||||
*/
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
#include "wirish_math.h"
|
||||
#include "limits.h"
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
/*
|
||||
* Note:
|
||||
*
|
||||
* At time of writing (12 April 2011), the limits.h that came with the
|
||||
* newlib we distributed didn't include LLONG_MAX. Because we're
|
||||
* staying away from using templates (see /notes/coding_standard.rst,
|
||||
* "Language Features and Compiler Extensions"), this value was
|
||||
* copy-pasted from a println() of the value
|
||||
*
|
||||
* std::numeric_limits<long long>::max().
|
||||
*/
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
size_t Print::write(const char *str) {
|
||||
size_t n = 0;
|
||||
while (*str) {
|
||||
write(*str++);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::write(const void *buffer, uint32 size) {
|
||||
size_t n = 0;
|
||||
uint8 *ch = (uint8*)buffer;
|
||||
while (size--) {
|
||||
write(*ch++);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::print(uint8 b, int base) {
|
||||
return print((uint64)b, base);
|
||||
}
|
||||
|
||||
size_t Print::print(const String &s)
|
||||
{
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t Print::print(char c) {
|
||||
return write(c);
|
||||
}
|
||||
|
||||
size_t Print::print(const char str[]) {
|
||||
return write(str);
|
||||
}
|
||||
|
||||
size_t Print::print(int n, int base) {
|
||||
return print((long long)n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned int n, int base) {
|
||||
return print((unsigned long long)n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(long n, int base) {
|
||||
return print((long long)n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned long n, int base) {
|
||||
return print((unsigned long long)n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(long long n, int base) {
|
||||
if (n < 0) {
|
||||
print('-');
|
||||
n = -n;
|
||||
}
|
||||
return printNumber(n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned long long n, int base) {
|
||||
return printNumber(n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(double n, int digits) {
|
||||
return printFloat(n, digits);
|
||||
}
|
||||
|
||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
return print(reinterpret_cast<const char *>(ifsh));
|
||||
}
|
||||
|
||||
size_t Print::print(const Printable& x)
|
||||
{
|
||||
return x.printTo(*this);
|
||||
}
|
||||
|
||||
size_t Print::println(void)
|
||||
{
|
||||
size_t n = print('\r');
|
||||
n += print('\n');
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(const String &s)
|
||||
{
|
||||
size_t n = print(s);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(char c) {
|
||||
size_t n = print(c);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(const char c[]) {
|
||||
size_t n = print(c);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(uint8 b, int base) {
|
||||
size_t n = print(b, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(int n, int base) {
|
||||
size_t s = print(n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned int n, int base) {
|
||||
size_t s = print(n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(long n, int base) {
|
||||
size_t s = print((long long)n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned long n, int base) {
|
||||
size_t s = print((unsigned long long)n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(long long n, int base) {
|
||||
size_t s = print(n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned long long n, int base) {
|
||||
size_t s = print(n, base);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(double n, int digits) {
|
||||
size_t s = print(n, digits);
|
||||
s += println();
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t Print::println(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
size_t n = print(ifsh);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(const Printable& x)
|
||||
{
|
||||
size_t n = print(x);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_PRINTF
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
// Work in progress to support printf.
|
||||
// Need to implement stream FILE to write individual chars to chosen serial port
|
||||
int Print::printf (__const char *__restrict __format, ...)
|
||||
{
|
||||
FILE *__restrict __stream;
|
||||
int ret_status = 0;
|
||||
|
||||
|
||||
va_list args;
|
||||
va_start(args,__format);
|
||||
ret_status = vfprintf(__stream, __format, args);
|
||||
va_end(args);
|
||||
return ret_status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
size_t Print::printNumber(unsigned long long n, uint8 base) {
|
||||
unsigned char buf[CHAR_BIT * sizeof(long long)];
|
||||
unsigned long i = 0;
|
||||
size_t s=0;
|
||||
if (n == 0) {
|
||||
print('0');
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n > 0) {
|
||||
buf[i++] = n % base;
|
||||
n /= base;
|
||||
}
|
||||
|
||||
for (; i > 0; i--) {
|
||||
s += print((char)(buf[i - 1] < 10 ?
|
||||
'0' + buf[i - 1] :
|
||||
'A' + buf[i - 1] - 10));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* According to snprintf(),
|
||||
*
|
||||
* nextafter((double)numeric_limits<long long>::max(), 0.0) ~= 9.22337e+18
|
||||
*
|
||||
* This slightly smaller value was picked semi-arbitrarily. */
|
||||
#define LARGE_DOUBLE_TRESHOLD (9.1e18)
|
||||
|
||||
/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS.
|
||||
*
|
||||
* This implementation is meant to be simple and not occupy too much
|
||||
* code size. However, printing floating point values accurately is a
|
||||
* subtle task, best left to a well-tested library function.
|
||||
*
|
||||
* See Steele and White 2003 for more details:
|
||||
*
|
||||
* http://kurtstephens.com/files/p372-steele.pdf
|
||||
*/
|
||||
size_t Print::printFloat(double number, uint8 digits) {
|
||||
size_t s=0;
|
||||
// Hackish fail-fast behavior for large-magnitude doubles
|
||||
if (abs(number) >= LARGE_DOUBLE_TRESHOLD) {
|
||||
if (number < 0.0) {
|
||||
s=print('-');
|
||||
}
|
||||
s+=print("<large double>");
|
||||
return s;
|
||||
}
|
||||
|
||||
// Handle negative numbers
|
||||
if (number < 0.0) {
|
||||
s+=print('-');
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Simplistic rounding strategy so that e.g. print(1.999, 2)
|
||||
// prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
for (uint8 i = 0; i < digits; i++) {
|
||||
rounding /= 10.0;
|
||||
}
|
||||
number += rounding;
|
||||
|
||||
// Extract the integer part of the number and print it
|
||||
long long int_part = (long long)number;
|
||||
double remainder = number - int_part;
|
||||
s+=print(int_part);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits > 0) {
|
||||
s+=print(".");
|
||||
}
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
while (digits-- > 0) {
|
||||
remainder *= 10.0;
|
||||
int to_print = (int)remainder;
|
||||
s+=print(to_print);
|
||||
remainder -= to_print;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
88
BootLoaders/Boards/stm32/cores/maple/Print.h
Normal file
88
BootLoaders/Boards/stm32/cores/maple/Print.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Print.h - Base class that provides print() and println()
|
||||
* Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
*
|
||||
* 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 2.1 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA.
|
||||
*
|
||||
* Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com>
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_PRINT_H_
|
||||
#define _WIRISH_PRINT_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include "WString.h"
|
||||
#include "Printable.h"
|
||||
|
||||
enum {
|
||||
BIN = 2,
|
||||
OCT = 8,
|
||||
DEC = 10,
|
||||
HEX = 16
|
||||
};
|
||||
|
||||
class Print {
|
||||
public:
|
||||
virtual size_t write(uint8 ch) = 0;
|
||||
virtual size_t write(const char *str);
|
||||
virtual size_t write(const void *buf, uint32 len);
|
||||
|
||||
size_t print(const String &);
|
||||
size_t print(char);
|
||||
size_t print(const char[]);
|
||||
size_t print(uint8, int=DEC);
|
||||
size_t print(int, int=DEC);
|
||||
size_t print(unsigned int, int=DEC);
|
||||
size_t print(long, int=DEC);
|
||||
size_t print(unsigned long, int=DEC);
|
||||
size_t print(long long, int=DEC);
|
||||
size_t print(unsigned long long, int=DEC);
|
||||
size_t print(double, int=2);
|
||||
size_t print(const __FlashStringHelper *);
|
||||
size_t print(const Printable&);
|
||||
size_t println(void);
|
||||
size_t println(const String &s);
|
||||
size_t println(char);
|
||||
size_t println(const char[]);
|
||||
size_t println(uint8, int=DEC);
|
||||
size_t println(int, int=DEC);
|
||||
size_t println(unsigned int, int=DEC);
|
||||
size_t println(long, int=DEC);
|
||||
size_t println(unsigned long, int=DEC);
|
||||
size_t println(long long, int=DEC);
|
||||
size_t println(unsigned long long, int=DEC);
|
||||
size_t println(double, int=2);
|
||||
size_t println(const __FlashStringHelper *);
|
||||
size_t println(const Printable&);
|
||||
#ifdef SUPPORTS_PRINTF
|
||||
// Roger Clark. Work in progress to add printf support
|
||||
int printf(const char * format, ...);
|
||||
#endif
|
||||
Print() : write_error(0) {}
|
||||
|
||||
int getWriteError() { return write_error; }
|
||||
void clearWriteError() { setWriteError(0); }
|
||||
|
||||
protected:
|
||||
void setWriteError(int err = 1) { write_error = err; }
|
||||
|
||||
private:
|
||||
int write_error;
|
||||
size_t printNumber(unsigned long long, uint8);
|
||||
size_t printFloat(double, uint8);
|
||||
};
|
||||
|
||||
#endif
|
40
BootLoaders/Boards/stm32/cores/maple/Printable.h
Normal file
40
BootLoaders/Boards/stm32/cores/maple/Printable.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Printable.h - Interface class that allows printing of complex types
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Printable_h
|
||||
#define Printable_h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class Print;
|
||||
|
||||
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
||||
By deriving from Printable and implementing the printTo method, it will then be possible
|
||||
for users to print out instances of this class by passing them into the usual
|
||||
Print::print and Print::println methods.
|
||||
*/
|
||||
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
30
BootLoaders/Boards/stm32/cores/maple/Server.h
Normal file
30
BootLoaders/Boards/stm32/cores/maple/Server.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Server.h - Base class that provides Server
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef server_h
|
||||
#define server_h
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
class Server : public Print {
|
||||
public:
|
||||
virtual void begin() =0;
|
||||
};
|
||||
|
||||
#endif
|
335
BootLoaders/Boards/stm32/cores/maple/Stream.cpp
Normal file
335
BootLoaders/Boards/stm32/cores/maple/Stream.cpp
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
Stream.cpp - adds parsing methods to Stream class
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Created July 2011
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
|
||||
|
||||
// private method to read stream with timeout
|
||||
int Stream::timedRead()
|
||||
{
|
||||
int c;
|
||||
_startMillis = millis();
|
||||
do {
|
||||
c = read();
|
||||
if (c >= 0) return c;
|
||||
} while(millis() - _startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// private method to peek stream with timeout
|
||||
int Stream::timedPeek()
|
||||
{
|
||||
int c;
|
||||
_startMillis = millis();
|
||||
do {
|
||||
c = peek();
|
||||
if (c >= 0) return c;
|
||||
} while(millis() - _startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// returns peek of the next digit in the stream or -1 if timeout
|
||||
// discards non-numeric characters
|
||||
int Stream::peekNextDigit()
|
||||
{
|
||||
int c;
|
||||
while (1) {
|
||||
c = timedPeek();
|
||||
if (c < 0) return c; // timeout
|
||||
if (c == '-') return c;
|
||||
if (c >= '0' && c <= '9') return c;
|
||||
read(); // discard non-numeric
|
||||
}
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
// find returns true if the target string is found
|
||||
bool Stream::find(char *target)
|
||||
{
|
||||
return findUntil(target, (char*)"");
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of given length is found
|
||||
// returns true if target string is found, false if timed out
|
||||
bool Stream::find(char *target, size_t length)
|
||||
{
|
||||
return findUntil(target, length, NULL, 0);
|
||||
}
|
||||
|
||||
// as find but search ends if the terminator string is found
|
||||
bool Stream::findUntil(char *target, char *terminator)
|
||||
{
|
||||
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of the given length is found
|
||||
// search terminated if the terminator string is found
|
||||
// returns true if target string is found, false if terminated or timed out
|
||||
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
|
||||
{
|
||||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
if( *target == 0)
|
||||
return true; // return true if target is a null string
|
||||
while( (c = timedRead()) > 0){
|
||||
|
||||
if(c != target[index])
|
||||
index = 0; // reset index if any char does not match
|
||||
|
||||
if( c == target[index]){
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen){ // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(termLen > 0 && c == terminator[termIndex]){
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
else
|
||||
termIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// function is terminated by the first character that is not a digit.
|
||||
long Stream::parseInt()
|
||||
{
|
||||
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
|
||||
}
|
||||
|
||||
// as above but a given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
long Stream::parseInt(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore this charactor
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if(c >= '0' && c <= '9') // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// as parseInt but returns a floating point value
|
||||
float Stream::parseFloat()
|
||||
{
|
||||
return parseFloat(NO_SKIP_CHAR);
|
||||
}
|
||||
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
float Stream::parseFloat(char skipChar){
|
||||
boolean isNegative = false;
|
||||
boolean isFraction = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
float fraction = 1.0;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if (c == '.')
|
||||
isFraction = true;
|
||||
else if(c >= '0' && c <= '9') { // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
if(isFraction)
|
||||
fraction *= 0.1;
|
||||
}
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
if(isFraction)
|
||||
return value * fraction;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
// read characters from stream into buffer
|
||||
// terminates if length characters have been read, or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer
|
||||
// the buffer is NOT null terminated.
|
||||
//
|
||||
size_t Stream::readBytes(char *buffer, size_t length)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0) break;
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
// as readBytes with terminator character
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||
{
|
||||
if (length < 1) return 0;
|
||||
size_t index = 0;
|
||||
while (index < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0 || c == terminator) break;
|
||||
*buffer++ = (char)c;
|
||||
index++;
|
||||
}
|
||||
return index; // return number of characters, not including null terminator
|
||||
}
|
||||
|
||||
String Stream::readString()
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while (c >= 0)
|
||||
{
|
||||
ret += (char)c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String Stream::readStringUntil(char terminator)
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while (c >= 0 && c != terminator)
|
||||
{
|
||||
ret += (char)c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
|
||||
// any zero length target string automatically matches and would make
|
||||
// a mess of the rest of the algorithm.
|
||||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
||||
if (t->len <= 0)
|
||||
return t - targets;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int c = timedRead();
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
||||
// the simple case is if we match, deal with that first.
|
||||
if (c == t->str[t->index]) {
|
||||
if (++t->index == t->len)
|
||||
return t - targets;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
// if not we need to walk back and see if we could have matched further
|
||||
// down the stream (ie '1112' doesn't match the first position in '11112'
|
||||
// but it will match the second position so we can't just reset the current
|
||||
// index to 0 when we find a mismatch.
|
||||
if (t->index == 0)
|
||||
continue;
|
||||
|
||||
int origIndex = t->index;
|
||||
do {
|
||||
--t->index;
|
||||
// first check if current char works against the new current index
|
||||
if (c != t->str[t->index])
|
||||
continue;
|
||||
|
||||
// if it's the only char then we're good, nothing more to check
|
||||
if (t->index == 0) {
|
||||
t->index++;
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise we need to check the rest of the found string
|
||||
int diff = origIndex - t->index;
|
||||
size_t i;
|
||||
for (i = 0; i < t->index; ++i) {
|
||||
if (t->str[i] != t->str[i + diff])
|
||||
break;
|
||||
}
|
||||
|
||||
// if we successfully got through the previous loop then our current
|
||||
// index is good.
|
||||
if (i == t->index) {
|
||||
t->index++;
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise we just try the next index
|
||||
} while (t->index);
|
||||
}
|
||||
}
|
||||
// unreachable
|
||||
return -1;
|
||||
}
|
115
BootLoaders/Boards/stm32/cores/maple/Stream.h
Normal file
115
BootLoaders/Boards/stm32/cores/maple/Stream.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
// compatability macros for testing
|
||||
/*
|
||||
#define getInt() parseInt()
|
||||
#define getInt(skipChar) parseInt(skipchar)
|
||||
#define getFloat() parseFloat()
|
||||
#define getFloat(skipChar) parseFloat(skipChar)
|
||||
#define getString( pre_string, post_string, buffer, length)
|
||||
readBytesBetween( pre_string, terminator, buffer, length)
|
||||
*/
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
protected:
|
||||
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||
unsigned long _startMillis; // used for timeout measurement
|
||||
int timedRead(); // private method to read stream with timeout
|
||||
int timedPeek(); // private method to peek stream with timeout
|
||||
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
|
||||
|
||||
public:
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
Stream() {_timeout=1000;}
|
||||
|
||||
// parsing methods
|
||||
|
||||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||
unsigned long getTimeout(void) { return _timeout; }
|
||||
|
||||
bool find(char *target); // reads data from the stream until the target string is found
|
||||
bool find(uint8_t *target) { return find ((char *)target); }
|
||||
// returns true if target string is found, false if timed out (see setTimeout)
|
||||
|
||||
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
|
||||
// returns true if target string is found, false if timed out
|
||||
|
||||
bool find(char target) { return find (&target, 1); }
|
||||
|
||||
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
|
||||
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
|
||||
|
||||
|
||||
long parseInt(); // returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// integer is terminated by the first character that is not a digit.
|
||||
|
||||
float parseFloat(); // float version of parseInt
|
||||
|
||||
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
|
||||
// terminates if length characters have been read or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
// Arduino String functions to be added here
|
||||
String readString();
|
||||
String readStringUntil(char terminator);
|
||||
|
||||
protected:
|
||||
long parseInt(char skipChar); // as above but the given skipChar is ignored
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
|
||||
float parseFloat(char skipChar); // as above but the given skipChar is ignored
|
||||
|
||||
struct MultiTarget {
|
||||
const char *str; // string you're searching for
|
||||
size_t len; // length of string you're searching for
|
||||
size_t index; // index used by the search routine.
|
||||
};
|
||||
|
||||
// This allows you to search for an arbitrary number of strings.
|
||||
// Returns index of the target that is found first or -1 if timeout occurs.
|
||||
int findMulti(struct MultiTarget *targets, int tCount);
|
||||
};
|
||||
|
||||
#endif
|
88
BootLoaders/Boards/stm32/cores/maple/Udp.h
Normal file
88
BootLoaders/Boards/stm32/cores/maple/Udp.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets.
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#ifndef udp_h
|
||||
#define udp_h
|
||||
|
||||
#include <Stream.h>
|
||||
#include <IPAddress.h>
|
||||
|
||||
class UDP : public Stream {
|
||||
|
||||
public:
|
||||
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop() =0; // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port) =0;
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket() =0;
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t) =0;
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) =0;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket() =0;
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available() =0;
|
||||
// Read a single byte from the current packet
|
||||
virtual int read() =0;
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len) =0;
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) =0;
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek() =0;
|
||||
virtual void flush() =0; // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() =0;
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() =0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
180
BootLoaders/Boards/stm32/cores/maple/WCharacter.h
Normal file
180
BootLoaders/Boards/stm32/cores/maple/WCharacter.h
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
WCharacter.h - Character utility functions for Wiring & Arduino
|
||||
Copyright (c) 2010 Hernando Barragan. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Character_h
|
||||
#define Character_h
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// WCharacter.h prototypes
|
||||
#if defined ( __GNUC__ )
|
||||
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
|
||||
inline boolean isAlpha(int c) __attribute__((always_inline));
|
||||
inline boolean isAscii(int c) __attribute__((always_inline));
|
||||
inline boolean isWhitespace(int c) __attribute__((always_inline));
|
||||
inline boolean isControl(int c) __attribute__((always_inline));
|
||||
inline boolean isDigit(int c) __attribute__((always_inline));
|
||||
inline boolean isGraph(int c) __attribute__((always_inline));
|
||||
inline boolean isLowerCase(int c) __attribute__((always_inline));
|
||||
inline boolean isPrintable(int c) __attribute__((always_inline));
|
||||
inline boolean isPunct(int c) __attribute__((always_inline));
|
||||
inline boolean isSpace(int c) __attribute__((always_inline));
|
||||
inline boolean isUpperCase(int c) __attribute__((always_inline));
|
||||
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
|
||||
inline int toAscii(int c) __attribute__((always_inline));
|
||||
inline int toLowerCase(int c) __attribute__((always_inline));
|
||||
inline int toUpperCase(int c)__attribute__((always_inline));
|
||||
#elif defined ( __ICCARM__ )
|
||||
#endif
|
||||
|
||||
// Checks for an alphanumeric character.
|
||||
// It is equivalent to (isalpha(c) || isdigit(c)).
|
||||
inline boolean isAlphaNumeric(int c)
|
||||
{
|
||||
return ( isalnum(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for an alphabetic character.
|
||||
// It is equivalent to (isupper(c) || islower(c)).
|
||||
inline boolean isAlpha(int c)
|
||||
{
|
||||
return ( isalpha(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks whether c is a 7-bit unsigned char value
|
||||
// that fits into the ASCII character set.
|
||||
inline boolean isAscii(int c)
|
||||
{
|
||||
/* return ( isascii(c) == 0 ? false : true); */
|
||||
return ( (c & ~0x7f) != 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for a blank character, that is, a space or a tab.
|
||||
inline boolean isWhitespace(int c)
|
||||
{
|
||||
return ( isblank (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for a control character.
|
||||
inline boolean isControl(int c)
|
||||
{
|
||||
return ( iscntrl (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for a digit (0 through 9).
|
||||
inline boolean isDigit(int c)
|
||||
{
|
||||
return ( isdigit (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for any printable character except space.
|
||||
inline boolean isGraph(int c)
|
||||
{
|
||||
return ( isgraph (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for a lower-case character.
|
||||
inline boolean isLowerCase(int c)
|
||||
{
|
||||
return (islower (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for any printable character including space.
|
||||
inline boolean isPrintable(int c)
|
||||
{
|
||||
return ( isprint (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for any printable character which is not a space
|
||||
// or an alphanumeric character.
|
||||
inline boolean isPunct(int c)
|
||||
{
|
||||
return ( ispunct (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for white-space characters. For the avr-libc library,
|
||||
// these are: space, formfeed ('\f'), newline ('\n'), carriage
|
||||
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
|
||||
inline boolean isSpace(int c)
|
||||
{
|
||||
return ( isspace (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for an uppercase letter.
|
||||
inline boolean isUpperCase(int c)
|
||||
{
|
||||
return ( isupper (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
|
||||
// 8 9 a b c d e f A B C D E F.
|
||||
inline boolean isHexadecimalDigit(int c)
|
||||
{
|
||||
return ( isxdigit (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
|
||||
// Converts c to a 7-bit unsigned char value that fits into the
|
||||
// ASCII character set, by clearing the high-order bits.
|
||||
inline int toAscii(int c)
|
||||
{
|
||||
/* return toascii (c); */
|
||||
return (c & 0x7f);
|
||||
}
|
||||
|
||||
|
||||
// Warning:
|
||||
// Many people will be unhappy if you use this function.
|
||||
// This function will convert accented letters into random
|
||||
// characters.
|
||||
|
||||
// Converts the letter c to lower case, if possible.
|
||||
inline int toLowerCase(int c)
|
||||
{
|
||||
return tolower (c);
|
||||
}
|
||||
|
||||
|
||||
// Converts the letter c to upper case, if possible.
|
||||
inline int toUpperCase(int c)
|
||||
{
|
||||
return toupper (c);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
35
BootLoaders/Boards/stm32/cores/maple/WProgram.h
Normal file
35
BootLoaders/Boards/stm32/cores/maple/WProgram.h
Normal file
@ -0,0 +1,35 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _WIRISH_WPROGRAM_H_
|
||||
#define _WIRISH_WPROGRAM_H_
|
||||
|
||||
#include <wirish.h>
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
|
||||
#endif
|
747
BootLoaders/Boards/stm32/cores/maple/WString.cpp
Normal file
747
BootLoaders/Boards/stm32/cores/maple/WString.cpp
Normal file
@ -0,0 +1,747 @@
|
||||
/*
|
||||
WString.cpp - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WString.h"
|
||||
#include "itoa.h"
|
||||
#include "avr/dtostrf.h"
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
/*********************************************/
|
||||
|
||||
String::String(const char *cstr)
|
||||
{
|
||||
init();
|
||||
if (cstr) copy(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
String::String(const String &value)
|
||||
{
|
||||
init();
|
||||
*this = value;
|
||||
}
|
||||
|
||||
String::String(const __FlashStringHelper *pstr)
|
||||
{
|
||||
init();
|
||||
*this = pstr;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
String::String(String &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
String::String(StringSumHelper &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
#endif
|
||||
|
||||
String::String(char c)
|
||||
{
|
||||
init();
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned char value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned char)];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[2 + 8 * sizeof(int)];
|
||||
itoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned int)];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[2 + 8 * sizeof(long)];
|
||||
ltoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned long)];
|
||||
ultoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(float value, unsigned char decimalPlaces)
|
||||
{
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
}
|
||||
|
||||
String::String(double value, unsigned char decimalPlaces)
|
||||
{
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Memory Management */
|
||||
/*********************************************/
|
||||
|
||||
inline void String::init(void)
|
||||
{
|
||||
buffer = NULL;
|
||||
capacity = 0;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
void String::invalidate(void)
|
||||
{
|
||||
if (buffer) free(buffer);
|
||||
buffer = NULL;
|
||||
capacity = len = 0;
|
||||
}
|
||||
|
||||
unsigned char String::reserve(unsigned int size)
|
||||
{
|
||||
if (buffer && capacity >= size) return 1;
|
||||
if (changeBuffer(size)) {
|
||||
if (len == 0) buffer[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char String::changeBuffer(unsigned int maxStrLen)
|
||||
{
|
||||
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
|
||||
if (newbuffer) {
|
||||
buffer = newbuffer;
|
||||
capacity = maxStrLen;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Copy and Move */
|
||||
/*********************************************/
|
||||
|
||||
String & String::copy(const char *cstr, unsigned int length)
|
||||
{
|
||||
if (!reserve(length)) {
|
||||
invalidate();
|
||||
return *this;
|
||||
}
|
||||
len = length;
|
||||
strcpy(buffer, cstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
|
||||
{
|
||||
if (!reserve(length)) {
|
||||
invalidate();
|
||||
return *this;
|
||||
}
|
||||
len = length;
|
||||
strcpy_P(buffer, (PGM_P)pstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
void String::move(String &rhs)
|
||||
{
|
||||
if (buffer) {
|
||||
if (rhs && capacity >= rhs.len) {
|
||||
strcpy(buffer, rhs.buffer);
|
||||
len = rhs.len;
|
||||
rhs.len = 0;
|
||||
return;
|
||||
} else {
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
buffer = rhs.buffer;
|
||||
capacity = rhs.capacity;
|
||||
len = rhs.len;
|
||||
rhs.buffer = NULL;
|
||||
rhs.capacity = 0;
|
||||
rhs.len = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator = (const String &rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
|
||||
if (rhs.buffer) copy(rhs.buffer, rhs.len);
|
||||
else invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
String & String::operator = (String &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (StringSumHelper &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator = (const char *cstr)
|
||||
{
|
||||
if (cstr) copy(cstr, strlen(cstr));
|
||||
else invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (const __FlashStringHelper *pstr)
|
||||
{
|
||||
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
|
||||
else invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* concat */
|
||||
/*********************************************/
|
||||
|
||||
unsigned char String::concat(const String &s)
|
||||
{
|
||||
return concat(s.buffer, s.len);
|
||||
}
|
||||
|
||||
unsigned char String::concat(const char *cstr, unsigned int length)
|
||||
{
|
||||
unsigned int newlen = len + length;
|
||||
if (!cstr) return 0;
|
||||
if (length == 0) return 1;
|
||||
if (!reserve(newlen)) return 0;
|
||||
strcpy(buffer + len, cstr);
|
||||
len = newlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::concat(const char *cstr)
|
||||
{
|
||||
if (!cstr) return 0;
|
||||
return concat(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
unsigned char String::concat(char c)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
return concat(buf, 1);
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned char num)
|
||||
{
|
||||
char buf[1 + 3 * sizeof(unsigned char)];
|
||||
itoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(int num)
|
||||
{
|
||||
char buf[2 + 3 * sizeof(int)];
|
||||
itoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned int num)
|
||||
{
|
||||
char buf[1 + 3 * sizeof(unsigned int)];
|
||||
utoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(long num)
|
||||
{
|
||||
char buf[2 + 3 * sizeof(long)];
|
||||
ltoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned long num)
|
||||
{
|
||||
char buf[1 + 3 * sizeof(unsigned long)];
|
||||
ultoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(float num)
|
||||
{
|
||||
char buf[20];
|
||||
char* string = dtostrf(num, 4, 2, buf);
|
||||
return concat(string, strlen(string));
|
||||
}
|
||||
|
||||
unsigned char String::concat(double num)
|
||||
{
|
||||
char buf[20];
|
||||
char* string = dtostrf(num, 4, 2, buf);
|
||||
return concat(string, strlen(string));
|
||||
}
|
||||
|
||||
unsigned char String::concat(const __FlashStringHelper * str)
|
||||
{
|
||||
if (!str) return 0;
|
||||
int length = strlen_P((const char *) str);
|
||||
if (length == 0) return 1;
|
||||
unsigned int newlen = len + length;
|
||||
if (!reserve(newlen)) return 0;
|
||||
strcpy_P(buffer + len, (const char *) str);
|
||||
len = newlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Concatenate */
|
||||
/*********************************************/
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(c)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(num)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(rhs)) a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Comparison */
|
||||
/*********************************************/
|
||||
|
||||
int String::compareTo(const String &s) const
|
||||
{
|
||||
if (!buffer || !s.buffer) {
|
||||
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
|
||||
if (buffer && len > 0) return *(unsigned char *)buffer;
|
||||
return 0;
|
||||
}
|
||||
return strcmp(buffer, s.buffer);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const String &s2) const
|
||||
{
|
||||
return (len == s2.len && compareTo(s2) == 0);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const char *cstr) const
|
||||
{
|
||||
if (len == 0) return (cstr == NULL || *cstr == 0);
|
||||
if (cstr == NULL) return buffer[0] == 0;
|
||||
return strcmp(buffer, cstr) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char String::equalsIgnoreCase( const String &s2 ) const
|
||||
{
|
||||
if (this == &s2) return 1;
|
||||
if (len != s2.len) return 0;
|
||||
if (len == 0) return 1;
|
||||
const char *p1 = buffer;
|
||||
const char *p2 = s2.buffer;
|
||||
while (*p1) {
|
||||
if (tolower(*p1++) != tolower(*p2++)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2 ) const
|
||||
{
|
||||
if (len < s2.len) return 0;
|
||||
return startsWith(s2, 0);
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
|
||||
{
|
||||
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::endsWith( const String &s2 ) const
|
||||
{
|
||||
if ( len < s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Character Access */
|
||||
/*********************************************/
|
||||
|
||||
char String::charAt(unsigned int loc) const
|
||||
{
|
||||
return operator[](loc);
|
||||
}
|
||||
|
||||
void String::setCharAt(unsigned int loc, char c)
|
||||
{
|
||||
if (loc < len) buffer[loc] = c;
|
||||
}
|
||||
|
||||
char & String::operator[](unsigned int index)
|
||||
{
|
||||
static char dummy_writable_char;
|
||||
if (index >= len || !buffer) {
|
||||
dummy_writable_char = 0;
|
||||
return dummy_writable_char;
|
||||
}
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
char String::operator[]( unsigned int index ) const
|
||||
{
|
||||
if (index >= len || !buffer) return 0;
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
|
||||
{
|
||||
if (!bufsize || !buf) return;
|
||||
if (index >= len) {
|
||||
buf[0] = 0;
|
||||
return;
|
||||
}
|
||||
unsigned int n = bufsize - 1;
|
||||
if (n > len - index) n = len - index;
|
||||
strncpy((char *)buf, buffer + index, n);
|
||||
buf[n] = 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Search */
|
||||
/*********************************************/
|
||||
|
||||
int String::indexOf(char c) const
|
||||
{
|
||||
return indexOf(c, 0);
|
||||
}
|
||||
|
||||
int String::indexOf( char ch, unsigned int fromIndex ) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char* temp = strchr(buffer + fromIndex, ch);
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2) const
|
||||
{
|
||||
return indexOf(s2, 0);
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char *found = strstr(buffer + fromIndex, s2.buffer);
|
||||
if (found == NULL) return -1;
|
||||
return found - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf( char theChar ) const
|
||||
{
|
||||
return lastIndexOf(theChar, len - 1);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
char tempchar = buffer[fromIndex + 1];
|
||||
buffer[fromIndex + 1] = '\0';
|
||||
char* temp = strrchr( buffer, ch );
|
||||
buffer[fromIndex + 1] = tempchar;
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2) const
|
||||
{
|
||||
return lastIndexOf(s2, len - s2.len);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
|
||||
if (fromIndex >= len) fromIndex = len - 1;
|
||||
int found = -1;
|
||||
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
||||
p = strstr(p, s2.buffer);
|
||||
if (!p) break;
|
||||
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
String String::substring(unsigned int left, unsigned int right) const
|
||||
{
|
||||
if (left > right) {
|
||||
unsigned int temp = right;
|
||||
right = left;
|
||||
left = temp;
|
||||
}
|
||||
String out;
|
||||
if (left >= len) return out;
|
||||
if (right > len) right = len;
|
||||
char temp = buffer[right]; // save the replaced character
|
||||
buffer[right] = '\0';
|
||||
out = buffer + left; // pointer arithmetic
|
||||
buffer[right] = temp; //restore character
|
||||
return out;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Modification */
|
||||
/*********************************************/
|
||||
|
||||
void String::replace(char find, char replace)
|
||||
{
|
||||
if (!buffer) return;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
if (*p == find) *p = replace;
|
||||
}
|
||||
}
|
||||
|
||||
void String::replace(const String& find, const String& replace)
|
||||
{
|
||||
if (len == 0 || find.len == 0) return;
|
||||
int diff = replace.len - find.len;
|
||||
char *readFrom = buffer;
|
||||
char *foundAt;
|
||||
if (diff == 0) {
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
memcpy(foundAt, replace.buffer, replace.len);
|
||||
readFrom = foundAt + replace.len;
|
||||
}
|
||||
} else if (diff < 0) {
|
||||
char *writeTo = buffer;
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
unsigned int n = foundAt - readFrom;
|
||||
memcpy(writeTo, readFrom, n);
|
||||
writeTo += n;
|
||||
memcpy(writeTo, replace.buffer, replace.len);
|
||||
writeTo += replace.len;
|
||||
readFrom = foundAt + find.len;
|
||||
len += diff;
|
||||
}
|
||||
strcpy(writeTo, readFrom);
|
||||
} else {
|
||||
unsigned int size = len; // compute size needed for result
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
readFrom = foundAt + find.len;
|
||||
size += diff;
|
||||
}
|
||||
if (size == len) return;
|
||||
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
|
||||
int index = len - 1;
|
||||
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||
readFrom = buffer + index + find.len;
|
||||
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
|
||||
len += diff;
|
||||
buffer[len] = 0;
|
||||
memcpy(buffer + index, replace.buffer, replace.len);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void String::remove(unsigned int index){
|
||||
// Pass the biggest integer as the count. The remove method
|
||||
// below will take care of truncating it at the end of the
|
||||
// string.
|
||||
remove(index, (unsigned int)-1);
|
||||
}
|
||||
|
||||
void String::remove(unsigned int index, unsigned int count){
|
||||
if (index >= len) { return; }
|
||||
if (count <= 0) { return; }
|
||||
if (count > len - index) { count = len - index; }
|
||||
char *writeTo = buffer + index;
|
||||
len = len - count;
|
||||
strncpy(writeTo, buffer + index + count,len - index);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
|
||||
void String::toLowerCase(void)
|
||||
{
|
||||
if (!buffer) return;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = tolower(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void String::toUpperCase(void)
|
||||
{
|
||||
if (!buffer) return;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void String::trim(void)
|
||||
{
|
||||
if (!buffer || len == 0) return;
|
||||
char *begin = buffer;
|
||||
while (isspace(*begin)) begin++;
|
||||
char *end = buffer + len - 1;
|
||||
while (isspace(*end) && end >= begin) end--;
|
||||
len = end + 1 - begin;
|
||||
if (begin > buffer) memcpy(buffer, begin, len);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Parsing / Conversion */
|
||||
/*********************************************/
|
||||
|
||||
long String::toInt(void) const
|
||||
{
|
||||
if (buffer) return atol(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float String::toFloat(void) const
|
||||
{
|
||||
if (buffer) return float(atof(buffer));
|
||||
return 0;
|
||||
}
|
228
BootLoaders/Boards/stm32/cores/maple/WString.h
Normal file
228
BootLoaders/Boards/stm32/cores/maple/WString.h
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
WString.h - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef String_class_h
|
||||
#define String_class_h
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
// When compiling programs with this class, the following gcc parameters
|
||||
// dramatically increase performance and memory (RAM) efficiency, typically
|
||||
// with little or no increase in code size.
|
||||
// -felide-constructors
|
||||
// -std=c++0x
|
||||
|
||||
class __FlashStringHelper;
|
||||
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
|
||||
|
||||
// An inherited class for holding the result of a concatenation. These
|
||||
// result objects are assumed to be writable by subsequent concatenations.
|
||||
class StringSumHelper;
|
||||
|
||||
// The string class
|
||||
class String
|
||||
{
|
||||
// use a function pointer to allow for "if (s)" without the
|
||||
// complications of an operator bool(). for more information, see:
|
||||
// http://www.artima.com/cppsource/safebool.html
|
||||
typedef void (String::*StringIfHelperType)() const;
|
||||
void StringIfHelper() const {}
|
||||
|
||||
public:
|
||||
// constructors
|
||||
// creates a copy of the initial value.
|
||||
// if the initial value is null or invalid, or if memory allocation
|
||||
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
||||
// be false).
|
||||
String(const char *cstr = "");
|
||||
String(const String &str);
|
||||
String(const __FlashStringHelper *str);
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
String(String &&rval);
|
||||
String(StringSumHelper &&rval);
|
||||
#endif
|
||||
explicit String(char c);
|
||||
explicit String(unsigned char, unsigned char base=10);
|
||||
explicit String(int, unsigned char base=10);
|
||||
explicit String(unsigned int, unsigned char base=10);
|
||||
explicit String(long, unsigned char base=10);
|
||||
explicit String(unsigned long, unsigned char base=10);
|
||||
explicit String(float, unsigned char decimalPlaces=2);
|
||||
explicit String(double, unsigned char decimalPlaces=2);
|
||||
~String(void);
|
||||
|
||||
// memory management
|
||||
// return true on success, false on failure (in which case, the string
|
||||
// is left unchanged). reserve(0), if successful, will validate an
|
||||
// invalid string (i.e., "if (s)" will be true afterwards)
|
||||
unsigned char reserve(unsigned int size);
|
||||
inline unsigned int length(void) const {return len;}
|
||||
|
||||
// creates a copy of the assigned value. if the value is null or
|
||||
// invalid, or if the memory allocation fails, the string will be
|
||||
// marked as invalid ("if (s)" will be false).
|
||||
String & operator = (const String &rhs);
|
||||
String & operator = (const char *cstr);
|
||||
String & operator = (const __FlashStringHelper *str);
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
String & operator = (String &&rval);
|
||||
String & operator = (StringSumHelper &&rval);
|
||||
#endif
|
||||
|
||||
// concatenate (works w/ built-in types)
|
||||
|
||||
// returns true on success, false on failure (in which case, the string
|
||||
// is left unchanged). if the argument is null or invalid, the
|
||||
// concatenation is considered unsucessful.
|
||||
unsigned char concat(const String &str);
|
||||
unsigned char concat(const char *cstr);
|
||||
unsigned char concat(char c);
|
||||
unsigned char concat(unsigned char c);
|
||||
unsigned char concat(int num);
|
||||
unsigned char concat(unsigned int num);
|
||||
unsigned char concat(long num);
|
||||
unsigned char concat(unsigned long num);
|
||||
unsigned char concat(float num);
|
||||
unsigned char concat(double num);
|
||||
unsigned char concat(const __FlashStringHelper * str);
|
||||
|
||||
// if there's not enough memory for the concatenated value, the string
|
||||
// will be left unchanged (but this isn't signalled in any way)
|
||||
String & operator += (const String &rhs) {concat(rhs); return (*this);}
|
||||
String & operator += (const char *cstr) {concat(cstr); return (*this);}
|
||||
String & operator += (char c) {concat(c); return (*this);}
|
||||
String & operator += (unsigned char num) {concat(num); return (*this);}
|
||||
String & operator += (int num) {concat(num); return (*this);}
|
||||
String & operator += (unsigned int num) {concat(num); return (*this);}
|
||||
String & operator += (long num) {concat(num); return (*this);}
|
||||
String & operator += (unsigned long num) {concat(num); return (*this);}
|
||||
String & operator += (float num) {concat(num); return (*this);}
|
||||
String & operator += (double num) {concat(num); return (*this);}
|
||||
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
|
||||
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
|
||||
|
||||
// comparison (only works w/ Strings and "strings")
|
||||
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
|
||||
int compareTo(const String &s) const;
|
||||
unsigned char equals(const String &s) const;
|
||||
unsigned char equals(const char *cstr) const;
|
||||
unsigned char operator == (const String &rhs) const {return equals(rhs);}
|
||||
unsigned char operator == (const char *cstr) const {return equals(cstr);}
|
||||
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
|
||||
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
|
||||
unsigned char operator < (const String &rhs) const;
|
||||
unsigned char operator > (const String &rhs) const;
|
||||
unsigned char operator <= (const String &rhs) const;
|
||||
unsigned char operator >= (const String &rhs) const;
|
||||
unsigned char equalsIgnoreCase(const String &s) const;
|
||||
unsigned char startsWith( const String &prefix) const;
|
||||
unsigned char startsWith(const String &prefix, unsigned int offset) const;
|
||||
unsigned char endsWith(const String &suffix) const;
|
||||
|
||||
// character acccess
|
||||
char charAt(unsigned int index) const;
|
||||
void setCharAt(unsigned int index, char c);
|
||||
char operator [] (unsigned int index) const;
|
||||
char& operator [] (unsigned int index);
|
||||
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
|
||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
|
||||
{getBytes((unsigned char *)buf, bufsize, index);}
|
||||
const char * c_str() const { return buffer; }
|
||||
char* begin() { return buffer; }
|
||||
char* end() { return buffer + length(); }
|
||||
const char* begin() const { return c_str(); }
|
||||
const char* end() const { return c_str() + length(); }
|
||||
|
||||
// search
|
||||
int indexOf( char ch ) const;
|
||||
int indexOf( char ch, unsigned int fromIndex ) const;
|
||||
int indexOf( const String &str ) const;
|
||||
int indexOf( const String &str, unsigned int fromIndex ) const;
|
||||
int lastIndexOf( char ch ) const;
|
||||
int lastIndexOf( char ch, unsigned int fromIndex ) const;
|
||||
int lastIndexOf( const String &str ) const;
|
||||
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
|
||||
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
|
||||
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
|
||||
|
||||
// modification
|
||||
void replace(char find, char replace);
|
||||
void replace(const String& find, const String& replace);
|
||||
void remove(unsigned int index);
|
||||
void remove(unsigned int index, unsigned int count);
|
||||
void toLowerCase(void);
|
||||
void toUpperCase(void);
|
||||
void trim(void);
|
||||
|
||||
// parsing/conversion
|
||||
long toInt(void) const;
|
||||
float toFloat(void) const;
|
||||
|
||||
protected:
|
||||
char *buffer; // the actual char array
|
||||
unsigned int capacity; // the array length minus one (for the '\0')
|
||||
unsigned int len; // the String length (not counting the '\0')
|
||||
protected:
|
||||
void init(void);
|
||||
void invalidate(void);
|
||||
unsigned char changeBuffer(unsigned int maxStrLen);
|
||||
unsigned char concat(const char *cstr, unsigned int length);
|
||||
|
||||
// copy and move
|
||||
String & copy(const char *cstr, unsigned int length);
|
||||
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
void move(String &rhs);
|
||||
#endif
|
||||
};
|
||||
|
||||
class StringSumHelper : public String
|
||||
{
|
||||
public:
|
||||
StringSumHelper(const String &s) : String(s) {}
|
||||
StringSumHelper(const char *p) : String(p) {}
|
||||
StringSumHelper(char c) : String(c) {}
|
||||
StringSumHelper(unsigned char num) : String(num) {}
|
||||
StringSumHelper(int num) : String(num) {}
|
||||
StringSumHelper(unsigned int num) : String(num) {}
|
||||
StringSumHelper(long num) : String(num) {}
|
||||
StringSumHelper(unsigned long num) : String(num) {}
|
||||
StringSumHelper(float num) : String(num) {}
|
||||
StringSumHelper(double num) : String(num) {}
|
||||
};
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // String_class_h
|
29
BootLoaders/Boards/stm32/cores/maple/avr/dtostrf.c
Normal file
29
BootLoaders/Boards/stm32/cores/maple/avr/dtostrf.c
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
dtostrf - Emulation for dtostrf function from avr-libc
|
||||
Copyright (c) 2013 Arduino. All rights reserved.
|
||||
Written by Cristian Maglie <c.maglie@bug.st>
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
|
||||
char fmt[20];
|
||||
sprintf(fmt, "%%%d.%df", width, prec);
|
||||
sprintf(sout, fmt, val);
|
||||
return sout;
|
||||
}
|
||||
|
29
BootLoaders/Boards/stm32/cores/maple/avr/dtostrf.h
Normal file
29
BootLoaders/Boards/stm32/cores/maple/avr/dtostrf.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
dtostrf - Emulation for dtostrf function from avr-libc
|
||||
Copyright (c) 2013 Arduino. All rights reserved.
|
||||
Written by Cristian Maglie <c.maglie@bug.st>
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
44
BootLoaders/Boards/stm32/cores/maple/avr/pgmspace.h
Normal file
44
BootLoaders/Boards/stm32/cores/maple/avr/pgmspace.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __PGMSPACE_H_
|
||||
#define __PGMSPACE_H_ 1
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define PROGMEM
|
||||
#define PGM_P const char *
|
||||
#define PSTR(str) (str)
|
||||
|
||||
#define _SFR_BYTE(n) (n)
|
||||
|
||||
typedef void prog_void;
|
||||
typedef char prog_char;
|
||||
typedef unsigned char prog_uchar;
|
||||
typedef int8_t prog_int8_t;
|
||||
typedef uint8_t prog_uint8_t;
|
||||
typedef int16_t prog_int16_t;
|
||||
typedef uint16_t prog_uint16_t;
|
||||
typedef int32_t prog_int32_t;
|
||||
typedef uint32_t prog_uint32_t;
|
||||
|
||||
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
|
||||
#define strcpy_P(dest, src) strcpy((dest), (src))
|
||||
#define strcat_P(dest, src) strcat((dest), (src))
|
||||
#define strcmp_P(a, b) strcmp((a), (b))
|
||||
#define strstr_P(a, b) strstr((a), (b))
|
||||
#define strlen_P(a) strlen((a))
|
||||
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
|
||||
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
||||
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
|
||||
#define pgm_read_float(addr) (*(const float *)(addr))
|
||||
|
||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
||||
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
||||
#define pgm_read_float_near(addr) pgm_read_float(addr)
|
||||
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
|
||||
#define pgm_read_word_far(addr) pgm_read_word(addr)
|
||||
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
|
||||
#define pgm_read_float_far(addr) pgm_read_float(addr)
|
||||
|
||||
#endif
|
579
BootLoaders/Boards/stm32/cores/maple/bit_constants.h
Normal file
579
BootLoaders/Boards/stm32/cores/maple/bit_constants.h
Normal file
@ -0,0 +1,579 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief BIT[n] and binary literal defines, for Arduino
|
||||
* compatibility.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_BIT_CONSTANTS_H_
|
||||
#define _WIRISH_BIT_CONSTANTS_H_
|
||||
|
||||
#define BIT0 (1 << 0)
|
||||
#define BIT1 (1 << 1)
|
||||
#define BIT2 (1 << 2)
|
||||
#define BIT3 (1 << 3)
|
||||
#define BIT4 (1 << 4)
|
||||
#define BIT5 (1 << 5)
|
||||
#define BIT6 (1 << 6)
|
||||
#define BIT7 (1 << 7)
|
||||
#define BIT8 (1 << 8)
|
||||
#define BIT9 (1 << 9)
|
||||
#define BIT10 (1 << 10)
|
||||
#define BIT11 (1 << 11)
|
||||
#define BIT12 (1 << 12)
|
||||
#define BIT13 (1 << 13)
|
||||
#define BIT14 (1 << 14)
|
||||
#define BIT15 (1 << 15)
|
||||
#define BIT16 (1 << 16)
|
||||
#define BIT17 (1 << 17)
|
||||
#define BIT18 (1 << 18)
|
||||
#define BIT19 (1 << 19)
|
||||
#define BIT20 (1 << 20)
|
||||
#define BIT21 (1 << 21)
|
||||
#define BIT22 (1 << 22)
|
||||
#define BIT23 (1 << 23)
|
||||
#define BIT24 (1 << 24)
|
||||
#define BIT25 (1 << 25)
|
||||
#define BIT26 (1 << 26)
|
||||
#define BIT27 (1 << 27)
|
||||
#define BIT28 (1 << 28)
|
||||
#define BIT29 (1 << 29)
|
||||
#define BIT30 (1 << 30)
|
||||
#define BIT31 (1 << 31)
|
||||
|
||||
#define B0 0
|
||||
#define B00 0
|
||||
#define B000 0
|
||||
#define B0000 0
|
||||
#define B00000 0
|
||||
#define B000000 0
|
||||
#define B0000000 0
|
||||
#define B00000000 0
|
||||
#define B1 1
|
||||
#define B01 1
|
||||
#define B001 1
|
||||
#define B0001 1
|
||||
#define B00001 1
|
||||
#define B000001 1
|
||||
#define B0000001 1
|
||||
#define B00000001 1
|
||||
#define B10 2
|
||||
#define B010 2
|
||||
#define B0010 2
|
||||
#define B00010 2
|
||||
#define B000010 2
|
||||
#define B0000010 2
|
||||
#define B00000010 2
|
||||
#define B11 3
|
||||
#define B011 3
|
||||
#define B0011 3
|
||||
#define B00011 3
|
||||
#define B000011 3
|
||||
#define B0000011 3
|
||||
#define B00000011 3
|
||||
#define B100 4
|
||||
#define B0100 4
|
||||
#define B00100 4
|
||||
#define B000100 4
|
||||
#define B0000100 4
|
||||
#define B00000100 4
|
||||
#define B101 5
|
||||
#define B0101 5
|
||||
#define B00101 5
|
||||
#define B000101 5
|
||||
#define B0000101 5
|
||||
#define B00000101 5
|
||||
#define B110 6
|
||||
#define B0110 6
|
||||
#define B00110 6
|
||||
#define B000110 6
|
||||
#define B0000110 6
|
||||
#define B00000110 6
|
||||
#define B111 7
|
||||
#define B0111 7
|
||||
#define B00111 7
|
||||
#define B000111 7
|
||||
#define B0000111 7
|
||||
#define B00000111 7
|
||||
#define B1000 8
|
||||
#define B01000 8
|
||||
#define B001000 8
|
||||
#define B0001000 8
|
||||
#define B00001000 8
|
||||
#define B1001 9
|
||||
#define B01001 9
|
||||
#define B001001 9
|
||||
#define B0001001 9
|
||||
#define B00001001 9
|
||||
#define B1010 10
|
||||
#define B01010 10
|
||||
#define B001010 10
|
||||
#define B0001010 10
|
||||
#define B00001010 10
|
||||
#define B1011 11
|
||||
#define B01011 11
|
||||
#define B001011 11
|
||||
#define B0001011 11
|
||||
#define B00001011 11
|
||||
#define B1100 12
|
||||
#define B01100 12
|
||||
#define B001100 12
|
||||
#define B0001100 12
|
||||
#define B00001100 12
|
||||
#define B1101 13
|
||||
#define B01101 13
|
||||
#define B001101 13
|
||||
#define B0001101 13
|
||||
#define B00001101 13
|
||||
#define B1110 14
|
||||
#define B01110 14
|
||||
#define B001110 14
|
||||
#define B0001110 14
|
||||
#define B00001110 14
|
||||
#define B1111 15
|
||||
#define B01111 15
|
||||
#define B001111 15
|
||||
#define B0001111 15
|
||||
#define B00001111 15
|
||||
#define B10000 16
|
||||
#define B010000 16
|
||||
#define B0010000 16
|
||||
#define B00010000 16
|
||||
#define B10001 17
|
||||
#define B010001 17
|
||||
#define B0010001 17
|
||||
#define B00010001 17
|
||||
#define B10010 18
|
||||
#define B010010 18
|
||||
#define B0010010 18
|
||||
#define B00010010 18
|
||||
#define B10011 19
|
||||
#define B010011 19
|
||||
#define B0010011 19
|
||||
#define B00010011 19
|
||||
#define B10100 20
|
||||
#define B010100 20
|
||||
#define B0010100 20
|
||||
#define B00010100 20
|
||||
#define B10101 21
|
||||
#define B010101 21
|
||||
#define B0010101 21
|
||||
#define B00010101 21
|
||||
#define B10110 22
|
||||
#define B010110 22
|
||||
#define B0010110 22
|
||||
#define B00010110 22
|
||||
#define B10111 23
|
||||
#define B010111 23
|
||||
#define B0010111 23
|
||||
#define B00010111 23
|
||||
#define B11000 24
|
||||
#define B011000 24
|
||||
#define B0011000 24
|
||||
#define B00011000 24
|
||||
#define B11001 25
|
||||
#define B011001 25
|
||||
#define B0011001 25
|
||||
#define B00011001 25
|
||||
#define B11010 26
|
||||
#define B011010 26
|
||||
#define B0011010 26
|
||||
#define B00011010 26
|
||||
#define B11011 27
|
||||
#define B011011 27
|
||||
#define B0011011 27
|
||||
#define B00011011 27
|
||||
#define B11100 28
|
||||
#define B011100 28
|
||||
#define B0011100 28
|
||||
#define B00011100 28
|
||||
#define B11101 29
|
||||
#define B011101 29
|
||||
#define B0011101 29
|
||||
#define B00011101 29
|
||||
#define B11110 30
|
||||
#define B011110 30
|
||||
#define B0011110 30
|
||||
#define B00011110 30
|
||||
#define B11111 31
|
||||
#define B011111 31
|
||||
#define B0011111 31
|
||||
#define B00011111 31
|
||||
#define B100000 32
|
||||
#define B0100000 32
|
||||
#define B00100000 32
|
||||
#define B100001 33
|
||||
#define B0100001 33
|
||||
#define B00100001 33
|
||||
#define B100010 34
|
||||
#define B0100010 34
|
||||
#define B00100010 34
|
||||
#define B100011 35
|
||||
#define B0100011 35
|
||||
#define B00100011 35
|
||||
#define B100100 36
|
||||
#define B0100100 36
|
||||
#define B00100100 36
|
||||
#define B100101 37
|
||||
#define B0100101 37
|
||||
#define B00100101 37
|
||||
#define B100110 38
|
||||
#define B0100110 38
|
||||
#define B00100110 38
|
||||
#define B100111 39
|
||||
#define B0100111 39
|
||||
#define B00100111 39
|
||||
#define B101000 40
|
||||
#define B0101000 40
|
||||
#define B00101000 40
|
||||
#define B101001 41
|
||||
#define B0101001 41
|
||||
#define B00101001 41
|
||||
#define B101010 42
|
||||
#define B0101010 42
|
||||
#define B00101010 42
|
||||
#define B101011 43
|
||||
#define B0101011 43
|
||||
#define B00101011 43
|
||||
#define B101100 44
|
||||
#define B0101100 44
|
||||
#define B00101100 44
|
||||
#define B101101 45
|
||||
#define B0101101 45
|
||||
#define B00101101 45
|
||||
#define B101110 46
|
||||
#define B0101110 46
|
||||
#define B00101110 46
|
||||
#define B101111 47
|
||||
#define B0101111 47
|
||||
#define B00101111 47
|
||||
#define B110000 48
|
||||
#define B0110000 48
|
||||
#define B00110000 48
|
||||
#define B110001 49
|
||||
#define B0110001 49
|
||||
#define B00110001 49
|
||||
#define B110010 50
|
||||
#define B0110010 50
|
||||
#define B00110010 50
|
||||
#define B110011 51
|
||||
#define B0110011 51
|
||||
#define B00110011 51
|
||||
#define B110100 52
|
||||
#define B0110100 52
|
||||
#define B00110100 52
|
||||
#define B110101 53
|
||||
#define B0110101 53
|
||||
#define B00110101 53
|
||||
#define B110110 54
|
||||
#define B0110110 54
|
||||
#define B00110110 54
|
||||
#define B110111 55
|
||||
#define B0110111 55
|
||||
#define B00110111 55
|
||||
#define B111000 56
|
||||
#define B0111000 56
|
||||
#define B00111000 56
|
||||
#define B111001 57
|
||||
#define B0111001 57
|
||||
#define B00111001 57
|
||||
#define B111010 58
|
||||
#define B0111010 58
|
||||
#define B00111010 58
|
||||
#define B111011 59
|
||||
#define B0111011 59
|
||||
#define B00111011 59
|
||||
#define B111100 60
|
||||
#define B0111100 60
|
||||
#define B00111100 60
|
||||
#define B111101 61
|
||||
#define B0111101 61
|
||||
#define B00111101 61
|
||||
#define B111110 62
|
||||
#define B0111110 62
|
||||
#define B00111110 62
|
||||
#define B111111 63
|
||||
#define B0111111 63
|
||||
#define B00111111 63
|
||||
#define B1000000 64
|
||||
#define B01000000 64
|
||||
#define B1000001 65
|
||||
#define B01000001 65
|
||||
#define B1000010 66
|
||||
#define B01000010 66
|
||||
#define B1000011 67
|
||||
#define B01000011 67
|
||||
#define B1000100 68
|
||||
#define B01000100 68
|
||||
#define B1000101 69
|
||||
#define B01000101 69
|
||||
#define B1000110 70
|
||||
#define B01000110 70
|
||||
#define B1000111 71
|
||||
#define B01000111 71
|
||||
#define B1001000 72
|
||||
#define B01001000 72
|
||||
#define B1001001 73
|
||||
#define B01001001 73
|
||||
#define B1001010 74
|
||||
#define B01001010 74
|
||||
#define B1001011 75
|
||||
#define B01001011 75
|
||||
#define B1001100 76
|
||||
#define B01001100 76
|
||||
#define B1001101 77
|
||||
#define B01001101 77
|
||||
#define B1001110 78
|
||||
#define B01001110 78
|
||||
#define B1001111 79
|
||||
#define B01001111 79
|
||||
#define B1010000 80
|
||||
#define B01010000 80
|
||||
#define B1010001 81
|
||||
#define B01010001 81
|
||||
#define B1010010 82
|
||||
#define B01010010 82
|
||||
#define B1010011 83
|
||||
#define B01010011 83
|
||||
#define B1010100 84
|
||||
#define B01010100 84
|
||||
#define B1010101 85
|
||||
#define B01010101 85
|
||||
#define B1010110 86
|
||||
#define B01010110 86
|
||||
#define B1010111 87
|
||||
#define B01010111 87
|
||||
#define B1011000 88
|
||||
#define B01011000 88
|
||||
#define B1011001 89
|
||||
#define B01011001 89
|
||||
#define B1011010 90
|
||||
#define B01011010 90
|
||||
#define B1011011 91
|
||||
#define B01011011 91
|
||||
#define B1011100 92
|
||||
#define B01011100 92
|
||||
#define B1011101 93
|
||||
#define B01011101 93
|
||||
#define B1011110 94
|
||||
#define B01011110 94
|
||||
#define B1011111 95
|
||||
#define B01011111 95
|
||||
#define B1100000 96
|
||||
#define B01100000 96
|
||||
#define B1100001 97
|
||||
#define B01100001 97
|
||||
#define B1100010 98
|
||||
#define B01100010 98
|
||||
#define B1100011 99
|
||||
#define B01100011 99
|
||||
#define B1100100 100
|
||||
#define B01100100 100
|
||||
#define B1100101 101
|
||||
#define B01100101 101
|
||||
#define B1100110 102
|
||||
#define B01100110 102
|
||||
#define B1100111 103
|
||||
#define B01100111 103
|
||||
#define B1101000 104
|
||||
#define B01101000 104
|
||||
#define B1101001 105
|
||||
#define B01101001 105
|
||||
#define B1101010 106
|
||||
#define B01101010 106
|
||||
#define B1101011 107
|
||||
#define B01101011 107
|
||||
#define B1101100 108
|
||||
#define B01101100 108
|
||||
#define B1101101 109
|
||||
#define B01101101 109
|
||||
#define B1101110 110
|
||||
#define B01101110 110
|
||||
#define B1101111 111
|
||||
#define B01101111 111
|
||||
#define B1110000 112
|
||||
#define B01110000 112
|
||||
#define B1110001 113
|
||||
#define B01110001 113
|
||||
#define B1110010 114
|
||||
#define B01110010 114
|
||||
#define B1110011 115
|
||||
#define B01110011 115
|
||||
#define B1110100 116
|
||||
#define B01110100 116
|
||||
#define B1110101 117
|
||||
#define B01110101 117
|
||||
#define B1110110 118
|
||||
#define B01110110 118
|
||||
#define B1110111 119
|
||||
#define B01110111 119
|
||||
#define B1111000 120
|
||||
#define B01111000 120
|
||||
#define B1111001 121
|
||||
#define B01111001 121
|
||||
#define B1111010 122
|
||||
#define B01111010 122
|
||||
#define B1111011 123
|
||||
#define B01111011 123
|
||||
#define B1111100 124
|
||||
#define B01111100 124
|
||||
#define B1111101 125
|
||||
#define B01111101 125
|
||||
#define B1111110 126
|
||||
#define B01111110 126
|
||||
#define B1111111 127
|
||||
#define B01111111 127
|
||||
#define B10000000 128
|
||||
#define B10000001 129
|
||||
#define B10000010 130
|
||||
#define B10000011 131
|
||||
#define B10000100 132
|
||||
#define B10000101 133
|
||||
#define B10000110 134
|
||||
#define B10000111 135
|
||||
#define B10001000 136
|
||||
#define B10001001 137
|
||||
#define B10001010 138
|
||||
#define B10001011 139
|
||||
#define B10001100 140
|
||||
#define B10001101 141
|
||||
#define B10001110 142
|
||||
#define B10001111 143
|
||||
#define B10010000 144
|
||||
#define B10010001 145
|
||||
#define B10010010 146
|
||||
#define B10010011 147
|
||||
#define B10010100 148
|
||||
#define B10010101 149
|
||||
#define B10010110 150
|
||||
#define B10010111 151
|
||||
#define B10011000 152
|
||||
#define B10011001 153
|
||||
#define B10011010 154
|
||||
#define B10011011 155
|
||||
#define B10011100 156
|
||||
#define B10011101 157
|
||||
#define B10011110 158
|
||||
#define B10011111 159
|
||||
#define B10100000 160
|
||||
#define B10100001 161
|
||||
#define B10100010 162
|
||||
#define B10100011 163
|
||||
#define B10100100 164
|
||||
#define B10100101 165
|
||||
#define B10100110 166
|
||||
#define B10100111 167
|
||||
#define B10101000 168
|
||||
#define B10101001 169
|
||||
#define B10101010 170
|
||||
#define B10101011 171
|
||||
#define B10101100 172
|
||||
#define B10101101 173
|
||||
#define B10101110 174
|
||||
#define B10101111 175
|
||||
#define B10110000 176
|
||||
#define B10110001 177
|
||||
#define B10110010 178
|
||||
#define B10110011 179
|
||||
#define B10110100 180
|
||||
#define B10110101 181
|
||||
#define B10110110 182
|
||||
#define B10110111 183
|
||||
#define B10111000 184
|
||||
#define B10111001 185
|
||||
#define B10111010 186
|
||||
#define B10111011 187
|
||||
#define B10111100 188
|
||||
#define B10111101 189
|
||||
#define B10111110 190
|
||||
#define B10111111 191
|
||||
#define B11000000 192
|
||||
#define B11000001 193
|
||||
#define B11000010 194
|
||||
#define B11000011 195
|
||||
#define B11000100 196
|
||||
#define B11000101 197
|
||||
#define B11000110 198
|
||||
#define B11000111 199
|
||||
#define B11001000 200
|
||||
#define B11001001 201
|
||||
#define B11001010 202
|
||||
#define B11001011 203
|
||||
#define B11001100 204
|
||||
#define B11001101 205
|
||||
#define B11001110 206
|
||||
#define B11001111 207
|
||||
#define B11010000 208
|
||||
#define B11010001 209
|
||||
#define B11010010 210
|
||||
#define B11010011 211
|
||||
#define B11010100 212
|
||||
#define B11010101 213
|
||||
#define B11010110 214
|
||||
#define B11010111 215
|
||||
#define B11011000 216
|
||||
#define B11011001 217
|
||||
#define B11011010 218
|
||||
#define B11011011 219
|
||||
#define B11011100 220
|
||||
#define B11011101 221
|
||||
#define B11011110 222
|
||||
#define B11011111 223
|
||||
#define B11100000 224
|
||||
#define B11100001 225
|
||||
#define B11100010 226
|
||||
#define B11100011 227
|
||||
#define B11100100 228
|
||||
#define B11100101 229
|
||||
#define B11100110 230
|
||||
#define B11100111 231
|
||||
#define B11101000 232
|
||||
#define B11101001 233
|
||||
#define B11101010 234
|
||||
#define B11101011 235
|
||||
#define B11101100 236
|
||||
#define B11101101 237
|
||||
#define B11101110 238
|
||||
#define B11101111 239
|
||||
#define B11110000 240
|
||||
#define B11110001 241
|
||||
#define B11110010 242
|
||||
#define B11110011 243
|
||||
#define B11110100 244
|
||||
#define B11110101 245
|
||||
#define B11110110 246
|
||||
#define B11110111 247
|
||||
#define B11111000 248
|
||||
#define B11111001 249
|
||||
#define B11111010 250
|
||||
#define B11111011 251
|
||||
#define B11111100 252
|
||||
#define B11111101 253
|
||||
#define B11111110 254
|
||||
#define B11111111 255
|
||||
|
||||
#endif /* _BIT_CONSTANTS_H_ */
|
35
BootLoaders/Boards/stm32/cores/maple/bits.h
Normal file
35
BootLoaders/Boards/stm32/cores/maple/bits.h
Normal file
@ -0,0 +1,35 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/* Note: Use of this header file is deprecated. Use bit_constants.h
|
||||
instead. */
|
||||
|
||||
#ifndef _WIRISH_BITS_H_
|
||||
#define _WIRISH_BITS_H_
|
||||
|
||||
#include <bit_constants.h>
|
||||
|
||||
#endif
|
175
BootLoaders/Boards/stm32/cores/maple/boards.h
Normal file
175
BootLoaders/Boards/stm32/cores/maple/boards.h
Normal file
@ -0,0 +1,175 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Bryan Newbold.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/include/wirish/boards.h
|
||||
* @author Bryan Newbold <bnewbold@leaflabs.com>,
|
||||
* Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief init() and board-specific pin information.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_BOARDS_H_
|
||||
#define _WIRISH_BOARDS_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include <wirish_types.h>
|
||||
#include <board/board.h>
|
||||
|
||||
/* Set of all possible pin names; not all boards have all these (note
|
||||
* that we use the Dx convention since all of the Maple's pins are
|
||||
* "digital" pins (e.g. can be used with digitalRead() and
|
||||
* digitalWrite()), but not all of them are connected to ADCs. */
|
||||
enum {
|
||||
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16,
|
||||
D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31,
|
||||
D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46,
|
||||
D47, D48, D49, D50, D51, D52, D53, D54, D55, D56, D57, D58, D59, D60, D61,
|
||||
D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76,
|
||||
D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91,
|
||||
D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105,
|
||||
D106, D107, D108, D109, D110, D111, };
|
||||
|
||||
/**
|
||||
* @brief Maps each Maple pin to a corresponding stm32_pin_info.
|
||||
* @see stm32_pin_info
|
||||
*/
|
||||
extern const stm32_pin_info PIN_MAP[];
|
||||
|
||||
/**
|
||||
* @brief Pins capable of PWM output.
|
||||
*
|
||||
* Its length is BOARD_NR_PWM_PINS.
|
||||
*/
|
||||
extern const uint8 boardPWMPins[];
|
||||
|
||||
/**
|
||||
* @brief Array of pins capable of analog input.
|
||||
*
|
||||
* Its length is BOARD_NR_ADC_PINS.
|
||||
*/
|
||||
extern const uint8 boardADCPins[];
|
||||
|
||||
/**
|
||||
* @brief Pins which are connected to external hardware.
|
||||
*
|
||||
* For example, on Maple boards, it always at least includes
|
||||
* PB1 for the LED. Its length is BOARD_NR_USED_PINS.
|
||||
*/
|
||||
extern const uint8 boardUsedPins[];
|
||||
|
||||
/**
|
||||
* @brief Generic board initialization function.
|
||||
*
|
||||
* This function is called before main(). It ensures that the clocks
|
||||
* and peripherals are configured properly for use with wirish, then
|
||||
* calls boardInit().
|
||||
*
|
||||
* @see boardInit()
|
||||
*/
|
||||
void init(void);
|
||||
|
||||
/**
|
||||
* @brief Board-specific initialization function.
|
||||
*
|
||||
* This function is called from init() after all generic board
|
||||
* initialization has been performed. Each board is required to
|
||||
* define its own.
|
||||
*
|
||||
* @see init()
|
||||
*/
|
||||
extern void boardInit(void);
|
||||
|
||||
/**
|
||||
* @brief Test if a pin is used for a special purpose on your board.
|
||||
* @param pin Pin to test
|
||||
* @return true if the given pin is in boardUsedPins, and false otherwise.
|
||||
* @see boardUsedPins
|
||||
*/
|
||||
bool boardUsesPin(uint8 pin);
|
||||
|
||||
/*
|
||||
* Derived and default board definitions
|
||||
*/
|
||||
|
||||
#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND
|
||||
#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL)
|
||||
|
||||
#ifndef SYSTICK_RELOAD_VAL
|
||||
#define SYSTICK_RELOAD_VAL (1000 * CYCLES_PER_MICROSECOND - 1)
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_BUTTON_PRESSED_LEVEL
|
||||
#define BOARD_BUTTON_PRESSED_LEVEL HIGH
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Does the board break out a USART/UART's RX and TX pins?
|
||||
*
|
||||
* BOARD_HAVE_USART(n) is nonzero iff USARTn is available (n must be
|
||||
* an integer literal, 1 through 6). Also see BOARD_HAVE_USART1, ...,
|
||||
* BOARD_HAVE_UART4 (sic), etc.
|
||||
*/
|
||||
#define BOARD_HAVE_USART(n) (defined(BOARD_USART##n##_TX_PIN) && \
|
||||
defined(BOARD_USART##n##_RX_PIN))
|
||||
/** Feature test: nonzero iff the board has USART1. */
|
||||
#define BOARD_HAVE_USART1 BOARD_HAVE_USART(1)
|
||||
/** Feature test: nonzero iff the board has USART2, 0 otherwise. */
|
||||
#define BOARD_HAVE_USART2 BOARD_HAVE_USART(2)
|
||||
/** Feature test: nonzero iff the board has USART3, 0 otherwise. */
|
||||
#define BOARD_HAVE_USART3 BOARD_HAVE_USART(3)
|
||||
/** Feature test: nonzero iff the board has UART4, 0 otherwise. */
|
||||
#define BOARD_HAVE_UART4 BOARD_HAVE_USART(4)
|
||||
/** Feature test: nonzero iff the board has UART5, 0 otherwise. */
|
||||
#define BOARD_HAVE_UART5 BOARD_HAVE_USART(5)
|
||||
/** Feature test: nonzero iff the board has USART6, 0 otherwise. */
|
||||
#define BOARD_HAVE_USART6 BOARD_HAVE_USART(6)
|
||||
|
||||
/**
|
||||
* @brief Does the board break out a SPI peripheral's pins?
|
||||
*
|
||||
* BOARD_HAVE_SPI(n) is nonzero iff SPIn is available (n must be an
|
||||
* integer literal: 1, 2, or 3). Also see BOARD_HAVE_SPI1,
|
||||
* BOARD_HAVE_SPI2, BOARD_HAVE_SPI3. */
|
||||
#define BOARD_HAVE_SPI(n) (defined(BOARD_SPI##n##_NSS_PIN) && \
|
||||
defined(BOARD_SPI##n##_SCK_PIN) && \
|
||||
defined(BOARD_SPI##n##_MISO_PIN) && \
|
||||
defined(BOARD_SPI##n##_MOSI_PIN))
|
||||
/** Feature test: nonzero iff the board has SPI1. */
|
||||
#define BOARD_HAVE_SPI1 BOARD_HAVE_SPI(1)
|
||||
/** Feature test: nonzero iff the board has SPI2. */
|
||||
#define BOARD_HAVE_SPI2 BOARD_HAVE_SPI(2)
|
||||
/** Feature test: nonzero iff the board has SPI3. */
|
||||
#define BOARD_HAVE_SPI3 BOARD_HAVE_SPI(3)
|
||||
|
||||
/**
|
||||
* @brief Feature test: nonzero iff the board has SerialUSB.
|
||||
*/
|
||||
//Roger Clark. Change so that BOARD_HAVE_SERIALUSB is always true, so that it can be controller by -DSERIAL_USB
|
||||
#define BOARD_HAVE_SERIALUSB 1
|
||||
|
||||
/*(defined(BOARD_USB_DISC_DEV) && defined(BOARD_USB_DISC_BIT))*/
|
||||
|
||||
#endif
|
71
BootLoaders/Boards/stm32/cores/maple/boards_private.h
Normal file
71
BootLoaders/Boards/stm32/cores/maple/boards_private.h
Normal file
@ -0,0 +1,71 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/boards_private.h
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief Private board support header.
|
||||
*
|
||||
* This file declares chip-specific variables and functions which
|
||||
* determine how init() behaves. It is not part of the public Wirish
|
||||
* API, and can change without notice.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_BOARDS_PRIVATE_H_
|
||||
#define _WIRISH_BOARDS_PRIVATE_H_
|
||||
|
||||
#include <libmaple/rcc.h>
|
||||
#include <libmaple/adc.h>
|
||||
|
||||
/* Makes the PIN_MAP rows more human-readable. */
|
||||
#define PMAP_ROW(gpio_dev, gpio_bit, timer_dev, timer_ch, adc_dev, adc_ch) \
|
||||
{ gpio_dev, timer_dev, adc_dev, gpio_bit, timer_ch, adc_ch }
|
||||
|
||||
namespace wirish {
|
||||
namespace priv {
|
||||
|
||||
/*
|
||||
* Chip-specific initialization data
|
||||
*/
|
||||
|
||||
extern rcc_pll_cfg w_board_pll_cfg;
|
||||
extern adc_prescaler w_adc_pre;
|
||||
extern adc_smp_rate w_adc_smp;
|
||||
|
||||
/*
|
||||
* Chip-specific initialization routines and helper functions.
|
||||
*/
|
||||
|
||||
void board_reset_pll(void);
|
||||
void board_setup_clock_prescalers(void);
|
||||
void board_setup_gpio(void);
|
||||
void board_setup_usb(void);
|
||||
void series_init(void);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
6
BootLoaders/Boards/stm32/cores/maple/cxxabi-compat.cpp
Normal file
6
BootLoaders/Boards/stm32/cores/maple/cxxabi-compat.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
/* We compile with nodefaultlibs, so we need to provide an error
|
||||
* handler for an empty pure virtual function */
|
||||
extern "C" void __cxa_pure_virtual(void) {
|
||||
while(1)
|
||||
;
|
||||
}
|
90
BootLoaders/Boards/stm32/cores/maple/ext_interrupts.cpp
Normal file
90
BootLoaders/Boards/stm32/cores/maple/ext_interrupts.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/ext_interrupts.cpp
|
||||
* @brief Wiring-like interface for external interrupts
|
||||
*/
|
||||
|
||||
#include "ext_interrupts.h"
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/exti.h>
|
||||
|
||||
#include "boards.h"
|
||||
|
||||
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode);
|
||||
|
||||
void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) {
|
||||
if (pin >= BOARD_NR_GPIO_PINS || !handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
exti_trigger_mode outMode = exti_out_mode(mode);
|
||||
|
||||
exti_attach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit),
|
||||
gpio_exti_port(PIN_MAP[pin].gpio_device),
|
||||
handler,
|
||||
outMode);
|
||||
}
|
||||
|
||||
void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg,
|
||||
ExtIntTriggerMode mode) {
|
||||
if (pin >= BOARD_NR_GPIO_PINS || !handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
exti_trigger_mode outMode = exti_out_mode(mode);
|
||||
|
||||
exti_attach_callback((exti_num)(PIN_MAP[pin].gpio_bit),
|
||||
gpio_exti_port(PIN_MAP[pin].gpio_device),
|
||||
handler,
|
||||
arg,
|
||||
outMode);
|
||||
}
|
||||
|
||||
void detachInterrupt(uint8 pin) {
|
||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||
return;
|
||||
}
|
||||
|
||||
exti_detach_interrupt((exti_num)(PIN_MAP[pin].gpio_bit));
|
||||
}
|
||||
|
||||
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) {
|
||||
switch (mode) {
|
||||
case RISING:
|
||||
return EXTI_RISING;
|
||||
case FALLING:
|
||||
return EXTI_FALLING;
|
||||
case CHANGE:
|
||||
return EXTI_RISING_FALLING;
|
||||
}
|
||||
// Can't happen
|
||||
ASSERT(0);
|
||||
return (exti_trigger_mode)0;
|
||||
}
|
128
BootLoaders/Boards/stm32/cores/maple/ext_interrupts.h
Normal file
128
BootLoaders/Boards/stm32/cores/maple/ext_interrupts.h
Normal file
@ -0,0 +1,128 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/include/wirish/ext_interrupts.h
|
||||
* @brief Wiring-like external interrupt prototypes and types.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_EXT_INTERRUPTS_H_
|
||||
#define _WIRISH_EXT_INTERRUPTS_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include <libmaple/nvic.h>
|
||||
|
||||
/**
|
||||
* The kind of transition on an external pin which should trigger an
|
||||
* interrupt.
|
||||
*/
|
||||
typedef enum ExtIntTriggerMode {
|
||||
RISING, /**< To trigger an interrupt when the pin transitions LOW
|
||||
to HIGH */
|
||||
FALLING, /**< To trigger an interrupt when the pin transitions
|
||||
HIGH to LOW */
|
||||
CHANGE /**< To trigger an interrupt when the pin transitions from
|
||||
LOW to HIGH or HIGH to LOW (i.e., when the pin
|
||||
changes). */
|
||||
} ExtIntTriggerMode;
|
||||
|
||||
/**
|
||||
* @brief Registers an interrupt handler on a pin.
|
||||
*
|
||||
* The interrupt will be triggered on a given transition on the pin,
|
||||
* as specified by the mode parameter. The handler runs in interrupt
|
||||
* context. The new handler will replace whatever handler is
|
||||
* currently registered for the pin, if any.
|
||||
*
|
||||
* @param pin Pin number
|
||||
* @param handler Function to run upon external interrupt trigger.
|
||||
* The handler should take no arguments, and have void
|
||||
* return type.
|
||||
* @param mode Type of transition to trigger on, e.g. falling, rising, etc.
|
||||
*
|
||||
* @sideeffect Registers a handler
|
||||
* @see detachInterrupt()
|
||||
*/
|
||||
void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode);
|
||||
|
||||
/**
|
||||
* @brief Registers an interrupt handler on a pin.
|
||||
*
|
||||
* The interrupt will be triggered on a given transition on the pin,
|
||||
* as specified by the mode parameter. The handler runs in interrupt
|
||||
* context. The new handler will replace whatever handler is
|
||||
* currently registered for the pin, if any.
|
||||
*
|
||||
* @param pin Pin number
|
||||
* @param handler Static class member function to run upon external interrupt
|
||||
* trigger. The handler should take 1 argument and return void
|
||||
* @param arg Argument that the handler will be passed when it's called. One
|
||||
* use of this is to pass the specific instance of the class that
|
||||
* will handle the interrupt.
|
||||
* @param mode Type of transition to trigger on, e.g. falling, rising, etc.
|
||||
*
|
||||
* @sideeffect Registers a handler
|
||||
* @see detachInterrupt()
|
||||
*/
|
||||
void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg,
|
||||
ExtIntTriggerMode mode);
|
||||
|
||||
/**
|
||||
* @brief Disable any registered external interrupt.
|
||||
* @param pin Maple pin number
|
||||
* @sideeffect unregisters external interrupt handler
|
||||
* @see attachInterrupt()
|
||||
*/
|
||||
void detachInterrupt(uint8 pin);
|
||||
|
||||
/**
|
||||
* Re-enable interrupts.
|
||||
*
|
||||
* Call this after noInterrupts() to re-enable interrupt handling,
|
||||
* after you have finished with a timing-critical section of code.
|
||||
*
|
||||
* @see noInterrupts()
|
||||
*/
|
||||
static inline __always_inline void interrupts() {
|
||||
nvic_globalirq_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable interrupts.
|
||||
*
|
||||
* After calling this function, all user-programmable interrupts will
|
||||
* be disabled. You can call this function before a timing-critical
|
||||
* section of code, then call interrupts() to re-enable interrupt
|
||||
* handling.
|
||||
*
|
||||
* @see interrupts()
|
||||
*/
|
||||
static inline __always_inline void noInterrupts() {
|
||||
nvic_globalirq_disable();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
31
BootLoaders/Boards/stm32/cores/maple/hooks.c
Normal file
31
BootLoaders/Boards/stm32/cores/maple/hooks.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2012 Arduino. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Empty yield() hook.
|
||||
*
|
||||
* This function is intended to be used by library writers to build
|
||||
* libraries or sketches that supports cooperative threads.
|
||||
*
|
||||
* Its defined as a weak symbol and it can be redefined to implement a
|
||||
* real cooperative scheduler.
|
||||
*/
|
||||
static void __empty() {
|
||||
// Empty
|
||||
}
|
||||
void yield(void) __attribute__ ((weak, alias("__empty")));
|
165
BootLoaders/Boards/stm32/cores/maple/io.h
Normal file
165
BootLoaders/Boards/stm32/cores/maple/io.h
Normal file
@ -0,0 +1,165 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/include/wirish/io.h
|
||||
* @brief Wiring-style pin I/O interface.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_IO_H_
|
||||
#define _WIRISH_IO_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include <boards.h>
|
||||
|
||||
/**
|
||||
* Specifies a GPIO pin behavior.
|
||||
* @see pinMode()
|
||||
*/
|
||||
typedef enum WiringPinMode {
|
||||
OUTPUT, /**< Basic digital output: when the pin is HIGH, the
|
||||
voltage is held at +3.3v (Vcc) and when it is LOW, it
|
||||
is pulled down to ground. */
|
||||
|
||||
OUTPUT_OPEN_DRAIN, /**< In open drain mode, the pin indicates
|
||||
"low" by accepting current flow to ground
|
||||
and "high" by providing increased
|
||||
impedance. An example use would be to
|
||||
connect a pin to a bus line (which is pulled
|
||||
up to a positive voltage by a separate
|
||||
supply through a large resistor). When the
|
||||
pin is high, not much current flows through
|
||||
to ground and the line stays at positive
|
||||
voltage; when the pin is low, the bus
|
||||
"drains" to ground with a small amount of
|
||||
current constantly flowing through the large
|
||||
resistor from the external supply. In this
|
||||
mode, no current is ever actually sourced
|
||||
from the pin. */
|
||||
|
||||
INPUT, /**< Basic digital input. The pin voltage is sampled; when
|
||||
it is closer to 3.3v (Vcc) the pin status is high, and
|
||||
when it is closer to 0v (ground) it is low. If no
|
||||
external circuit is pulling the pin voltage to high or
|
||||
low, it will tend to randomly oscillate and be very
|
||||
sensitive to noise (e.g., a breath of air across the pin
|
||||
might cause the state to flip). */
|
||||
|
||||
INPUT_ANALOG, /**< This is a special mode for when the pin will be
|
||||
used for analog (not digital) reads. Enables ADC
|
||||
conversion to be performed on the voltage at the
|
||||
pin. */
|
||||
|
||||
INPUT_PULLUP, /**< The state of the pin in this mode is reported
|
||||
the same way as with INPUT, but the pin voltage
|
||||
is gently "pulled up" towards +3.3v. This means
|
||||
the state will be high unless an external device
|
||||
is specifically pulling the pin down to ground,
|
||||
in which case the "gentle" pull up will not
|
||||
affect the state of the input. */
|
||||
|
||||
INPUT_PULLDOWN, /**< The state of the pin in this mode is reported
|
||||
the same way as with INPUT, but the pin voltage
|
||||
is gently "pulled down" towards 0v. This means
|
||||
the state will be low unless an external device
|
||||
is specifically pulling the pin up to 3.3v, in
|
||||
which case the "gentle" pull down will not
|
||||
affect the state of the input. */
|
||||
|
||||
INPUT_FLOATING, /**< Synonym for INPUT. */
|
||||
|
||||
PWM, /**< This is a special mode for when the pin will be used for
|
||||
PWM output (a special case of digital output). */
|
||||
|
||||
PWM_OPEN_DRAIN, /**< Like PWM, except that instead of alternating
|
||||
cycles of LOW and HIGH, the voltage on the pin
|
||||
consists of alternating cycles of LOW and
|
||||
floating (disconnected). */
|
||||
} WiringPinMode;
|
||||
|
||||
/**
|
||||
* Configure behavior of a GPIO pin.
|
||||
*
|
||||
* @param pin Number of pin to configure.
|
||||
* @param mode Mode corresponding to desired pin behavior.
|
||||
* @see WiringPinMode
|
||||
*/
|
||||
void pinMode(uint8 pin, WiringPinMode mode);
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
/**
|
||||
* Writes a (digital) value to a pin. The pin must have its
|
||||
* mode set to OUTPUT or OUTPUT_OPEN_DRAIN.
|
||||
*
|
||||
* @param pin Pin to write to.
|
||||
* @param value Either LOW (write a 0) or HIGH (write a 1).
|
||||
* @see pinMode()
|
||||
*/
|
||||
void digitalWrite(uint8 pin, uint8 value);
|
||||
|
||||
/**
|
||||
* Read a digital value from a pin. The pin must have its mode set to
|
||||
* one of INPUT, INPUT_PULLUP, and INPUT_PULLDOWN.
|
||||
*
|
||||
* @param pin Pin to read from.
|
||||
* @return LOW or HIGH.
|
||||
* @see pinMode()
|
||||
*/
|
||||
uint32 digitalRead(uint8 pin);
|
||||
|
||||
/**
|
||||
* Read an analog value from pin. This function blocks during ADC
|
||||
* conversion, and has 12 bits of resolution. The pin must have its
|
||||
* mode set to INPUT_ANALOG.
|
||||
*
|
||||
* @param pin Pin to read from.
|
||||
* @return Converted voltage, in the range 0--4095, (i.e. a 12-bit ADC
|
||||
* conversion).
|
||||
* @see pinMode()
|
||||
*/
|
||||
uint16 analogRead(uint8 pin);
|
||||
|
||||
/**
|
||||
* Shift out a byte of data, one bit at a time.
|
||||
*
|
||||
* This function starts at either the most significant or least
|
||||
* significant bit in a byte value, and shifts out each byte in order
|
||||
* onto a data pin. After each bit is written to the data pin, a
|
||||
* separate clock pin is pulsed to indicate that the new bit is
|
||||
* available.
|
||||
*
|
||||
* @param dataPin Pin to shift data out on
|
||||
* @param clockPin Pin to pulse after each bit is shifted out
|
||||
* @param bitOrder Either MSBFIRST (big-endian) or LSBFIRST (little-endian).
|
||||
* @param value Value to shift out
|
||||
*/
|
||||
void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 value);
|
||||
|
||||
uint32 shiftIn( uint32 ulDataPin, uint32 ulClockPin, uint32 ulBitOrder );
|
||||
|
||||
#endif
|
174
BootLoaders/Boards/stm32/cores/maple/itoa.c
Normal file
174
BootLoaders/Boards/stm32/cores/maple/itoa.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
Copyright (c) 2011 Arduino. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "itoa.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif // __cplusplus
|
||||
|
||||
#if 0
|
||||
/* reverse: reverse string s in place */
|
||||
static void reverse( char s[] )
|
||||
{
|
||||
int i, j ;
|
||||
char c ;
|
||||
|
||||
for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- )
|
||||
{
|
||||
c = s[i] ;
|
||||
s[i] = s[j] ;
|
||||
s[j] = c ;
|
||||
}
|
||||
}
|
||||
|
||||
/* itoa: convert n to characters in s */
|
||||
extern void itoa( int n, char s[] )
|
||||
{
|
||||
int i, sign ;
|
||||
|
||||
if ( (sign = n) < 0 ) /* record sign */
|
||||
{
|
||||
n = -n; /* make n positive */
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do
|
||||
{ /* generate digits in reverse order */
|
||||
s[i++] = n % 10 + '0'; /* get next digit */
|
||||
} while ((n /= 10) > 0) ; /* delete it */
|
||||
|
||||
if (sign < 0 )
|
||||
{
|
||||
s[i++] = '-';
|
||||
}
|
||||
|
||||
s[i] = '\0';
|
||||
|
||||
reverse( s ) ;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern char* itoa( int value, char *string, int radix )
|
||||
{
|
||||
return ltoa( value, string, radix ) ;
|
||||
}
|
||||
|
||||
extern char* ltoa( long value, char *string, int radix )
|
||||
{
|
||||
char tmp[33];
|
||||
char *tp = tmp;
|
||||
long i;
|
||||
unsigned long v;
|
||||
int sign;
|
||||
char *sp;
|
||||
|
||||
if ( string == NULL )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if (radix > 36 || radix <= 1)
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
sign = (radix == 10 && value < 0);
|
||||
if (sign)
|
||||
{
|
||||
v = -value;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = (unsigned long)value;
|
||||
}
|
||||
|
||||
while (v || tp == tmp)
|
||||
{
|
||||
i = v % radix;
|
||||
v = v / radix;
|
||||
if (i < 10)
|
||||
*tp++ = i+'0';
|
||||
else
|
||||
*tp++ = i + 'a' - 10;
|
||||
}
|
||||
|
||||
sp = string;
|
||||
|
||||
if (sign)
|
||||
*sp++ = '-';
|
||||
while (tp > tmp)
|
||||
*sp++ = *--tp;
|
||||
*sp = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
|
||||
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
|
||||
extern char* utoa( unsigned value, char *string, int radix )
|
||||
#else
|
||||
extern char* utoa( unsigned int value, char *string, int radix )
|
||||
#endif
|
||||
{
|
||||
return ultoa( value, string, radix ) ;
|
||||
}
|
||||
|
||||
extern char* ultoa( unsigned long value, char *string, int radix )
|
||||
{
|
||||
char tmp[33];
|
||||
char *tp = tmp;
|
||||
long i;
|
||||
unsigned long v = value;
|
||||
char *sp;
|
||||
|
||||
if ( string == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (radix > 36 || radix <= 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (v || tp == tmp)
|
||||
{
|
||||
i = v % radix;
|
||||
v = v / radix;
|
||||
if (i < 10)
|
||||
*tp++ = i+'0';
|
||||
else
|
||||
*tp++ = i + 'a' - 10;
|
||||
}
|
||||
|
||||
sp = string;
|
||||
|
||||
|
||||
while (tp > tmp)
|
||||
*sp++ = *--tp;
|
||||
*sp = 0;
|
||||
|
||||
return string;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
47
BootLoaders/Boards/stm32/cores/maple/itoa.h
Normal file
47
BootLoaders/Boards/stm32/cores/maple/itoa.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2011 Arduino. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _ITOA_
|
||||
#define _ITOA_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif // __cplusplus
|
||||
|
||||
#if 0
|
||||
|
||||
extern void itoa( int n, char s[] ) ;
|
||||
|
||||
#else
|
||||
|
||||
extern char* itoa( int value, char *string, int radix ) ;
|
||||
extern char* ltoa( long value, char *string, int radix ) ;
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
|
||||
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
|
||||
extern char* utoa( unsigned value, char *string, int radix ) ;
|
||||
#else
|
||||
extern char* utoa( unsigned int value, char *string, int radix ) ;
|
||||
#endif
|
||||
extern char* ultoa( unsigned long value, char *string, int radix ) ;
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _ITOA_
|
110
BootLoaders/Boards/stm32/cores/maple/libmaple/adc.c
Normal file
110
BootLoaders/Boards/stm32/cores/maple/libmaple/adc.c
Normal file
@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/adc.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>,
|
||||
* Perry Hung <perry@leaflabs.com>
|
||||
* @brief Analog to digital converter routines
|
||||
*/
|
||||
|
||||
#include <libmaple/adc.h>
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize an ADC peripheral.
|
||||
*
|
||||
* Initializes the RCC clock line for the given peripheral. Resets
|
||||
* ADC device registers.
|
||||
*
|
||||
* @param dev ADC peripheral to initialize
|
||||
*/
|
||||
void adc_init(adc_dev *dev) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
rcc_reset_dev(dev->clk_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set external event select for regular group
|
||||
* @param dev ADC device
|
||||
* @param event Event used to trigger the start of conversion.
|
||||
* @see adc_extsel_event
|
||||
*/
|
||||
void adc_set_extsel(adc_dev *dev, adc_extsel_event event) {
|
||||
uint32 cr2 = dev->regs->CR2;
|
||||
cr2 &= ~ADC_CR2_EXTSEL;
|
||||
cr2 |= event;
|
||||
cr2 |= ADC_CR2_EXTTRIG;
|
||||
dev->regs->CR2 = cr2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the sample rate for all channels on an ADC device.
|
||||
*
|
||||
* Don't call this during conversion.
|
||||
*
|
||||
* @param dev adc device
|
||||
* @param smp_rate sample rate to set
|
||||
* @see adc_smp_rate
|
||||
*/
|
||||
void adc_set_sample_rate(adc_dev *dev, adc_smp_rate smp_rate) {
|
||||
uint32 adc_smpr1_val = 0, adc_smpr2_val = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (i < 8) {
|
||||
/* ADC_SMPR1 determines sample time for channels [10,17] */
|
||||
adc_smpr1_val |= smp_rate << (i * 3);
|
||||
}
|
||||
/* ADC_SMPR2 determines sample time for channels [0,9] */
|
||||
adc_smpr2_val |= smp_rate << (i * 3);
|
||||
}
|
||||
|
||||
dev->regs->SMPR1 = adc_smpr1_val;
|
||||
dev->regs->SMPR2 = adc_smpr2_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform a single synchronous software triggered conversion on a
|
||||
* channel.
|
||||
* @param dev ADC device to use for reading.
|
||||
* @param channel channel to convert
|
||||
* @return conversion result
|
||||
*/
|
||||
uint16 adc_read(adc_dev *dev, uint8 channel) {
|
||||
adc_reg_map *regs = dev->regs;
|
||||
|
||||
adc_set_reg_seqlen(dev, 1);
|
||||
|
||||
regs->SQR3 = channel;
|
||||
regs->CR2 |= ADC_CR2_SWSTART;
|
||||
while (!(regs->SR & ADC_SR_EOC))
|
||||
;
|
||||
|
||||
return (uint16)(regs->DR & ADC_DR_DATA);
|
||||
}
|
216
BootLoaders/Boards/stm32/cores/maple/libmaple/adc_f1.c
Normal file
216
BootLoaders/Boards/stm32/cores/maple/libmaple/adc_f1.c
Normal file
@ -0,0 +1,216 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/adc.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>,
|
||||
* Perry Hung <perry@leaflabs.com>
|
||||
* @brief STM32F1 ADC support.
|
||||
*/
|
||||
|
||||
#include <libmaple/adc.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/nvic.h>//Added by bubulindo.
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
adc_dev adc1 = {
|
||||
.regs = ADC1_BASE,
|
||||
.clk_id = RCC_ADC1,
|
||||
.handlers = {[3]=0}, //added by bubulindo. EOC, JEOC, AWD
|
||||
.irq_num = NVIC_ADC_1_2,
|
||||
};
|
||||
/** ADC1 device. */
|
||||
adc_dev *ADC1 = &adc1;
|
||||
|
||||
adc_dev adc2 = {
|
||||
.regs = ADC2_BASE,
|
||||
.clk_id = RCC_ADC2,
|
||||
};
|
||||
/** ADC2 device. */
|
||||
adc_dev *ADC2 = &adc2;
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
adc_dev adc3 = {
|
||||
.regs = ADC3_BASE,
|
||||
.clk_id = RCC_ADC3,
|
||||
.handlers = {[3]=0}, //added by bubulindo. EOC, JEOC, AWD
|
||||
.irq_num = NVIC_ADC3,//added by bubulindo.
|
||||
};
|
||||
/** ADC3 device. */
|
||||
adc_dev *ADC3 = &adc3;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
adc irq routine.
|
||||
Added by bubulindo.
|
||||
*/
|
||||
void __irq_adc() {
|
||||
//get status
|
||||
uint32 adc_sr = ADC1->regs->SR;
|
||||
//End Of Conversion
|
||||
if (adc_sr & (1U << ADC_SR_EOC_BIT)) {
|
||||
ADC1->regs->SR &= ~(1<<ADC_SR_EOC_BIT);
|
||||
void (*handler)(void) = ADC1->handlers[ADC_EOC];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
//Injected End Of Conversion
|
||||
if (adc_sr & (1U << ADC_SR_JEOC_BIT)) {
|
||||
ADC1->regs->SR &= ~(1<<ADC_SR_JEOC_BIT);
|
||||
void (*handler)(void) = ADC1->handlers[ADC_JEOC];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
//Analog Watchdog
|
||||
if (adc_sr & (1U << ADC_SR_AWD_BIT)) {
|
||||
ADC1->regs->SR &= ~(1<<ADC_SR_AWD_BIT);
|
||||
void (*handler)(void) = ADC1->handlers[ADC_AWD];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
};//end of adc irq
|
||||
|
||||
|
||||
/*
|
||||
ADC3 IRQ handler.
|
||||
added by bubulindo
|
||||
*/
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
void __irq_adc3() {
|
||||
//get status
|
||||
uint32 adc_sr = ADC3->regs->SR;
|
||||
//End Of Conversion
|
||||
if (adc_sr & (1U << ADC_SR_EOC_BIT)) {
|
||||
ADC3->regs->SR &= ~(1<<ADC_SR_EOC_BIT);
|
||||
void (*handler)(void) = ADC3->handlers[ADC_EOC];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
//Injected End Of Conversion
|
||||
if (adc_sr & (1U << ADC_SR_JEOC_BIT)) {
|
||||
ADC3->regs->SR &= ~(1<<ADC_SR_JEOC_BIT);
|
||||
void (*handler)(void) = ADC3->handlers[ADC_JEOC];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
//Analog Watchdog
|
||||
if (adc_sr & (1U << ADC_SR_AWD_BIT)) {
|
||||
ADC3->regs->SR &= ~(1<<ADC_SR_AWD_BIT);
|
||||
void (*handler)(void) = ADC3->handlers[ADC_AWD];
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
};//end of ADC3 irq
|
||||
#endif
|
||||
|
||||
/*
|
||||
enable interrupts on the ADC:
|
||||
use ADC_EOC, ADC_JEOC, ADC_AWD
|
||||
This will set up the interrupt bit in the ADC as well as in the NVIC.
|
||||
added by bubulindo
|
||||
*/
|
||||
void adc_enable_irq(adc_dev* dev, uint8 interrupt) {//ADC1 for now.
|
||||
dev->regs->CR1 |= (1U<<(interrupt +ADC_CR1_EOCIE_BIT));
|
||||
nvic_irq_enable(dev->irq_num);
|
||||
}
|
||||
|
||||
/*
|
||||
attach interrupt functionality for ADC
|
||||
use ADC_EOC, ADC_JEOC, ADC_AWD
|
||||
added by bubulindo
|
||||
*/
|
||||
|
||||
void adc_attach_interrupt(adc_dev *dev,
|
||||
uint8 interrupt,
|
||||
voidFuncPtr handler) {
|
||||
dev->handlers[interrupt] = handler;
|
||||
adc_enable_irq(dev, interrupt);
|
||||
//enable_irq(dev, interrupt); //I need to create this function. to enable NVIC
|
||||
// nvic_irq_enable()
|
||||
}
|
||||
|
||||
/*
|
||||
* STM32F1 routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Calibrate an ADC peripheral
|
||||
*
|
||||
* Availability: STM32F1.
|
||||
*
|
||||
* @param dev adc device
|
||||
*/
|
||||
void adc_calibrate(adc_dev *dev) {
|
||||
__io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3);
|
||||
__io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2);
|
||||
|
||||
*rstcal_bit = 1;
|
||||
while (*rstcal_bit)
|
||||
;
|
||||
|
||||
*cal_bit = 1;
|
||||
while (*cal_bit)
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routines
|
||||
*/
|
||||
|
||||
void adc_set_prescaler(adc_prescaler pre) {
|
||||
rcc_set_prescaler(RCC_PRESCALER_ADC, (uint32)pre);
|
||||
}
|
||||
|
||||
void adc_foreach(void (*fn)(adc_dev*)) {
|
||||
fn(ADC1);
|
||||
fn(ADC2);
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
fn(ADC3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void adc_config_gpio(adc_dev *ignored, gpio_dev *gdev, uint8 bit) {
|
||||
gpio_set_mode(gdev, bit, GPIO_INPUT_ANALOG);
|
||||
}
|
||||
|
||||
void adc_enable_single_swstart(adc_dev *dev) {
|
||||
adc_init(dev);
|
||||
adc_set_extsel(dev, ADC_SWSTART);
|
||||
adc_set_exttrig(dev, 1);
|
||||
adc_enable(dev);
|
||||
adc_calibrate(dev);
|
||||
}
|
129
BootLoaders/Boards/stm32/cores/maple/libmaple/bkp_f1.c
Normal file
129
BootLoaders/Boards/stm32/cores/maple/libmaple/bkp_f1.c
Normal file
@ -0,0 +1,129 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/bkp.c
|
||||
* @brief STM32F1 Backup register support.
|
||||
*/
|
||||
|
||||
#include <libmaple/bkp.h>
|
||||
#include <libmaple/pwr.h>
|
||||
#include <libmaple/rcc.h>
|
||||
#include <libmaple/bitband.h>
|
||||
|
||||
static inline __io uint32* data_register(uint8 reg);
|
||||
|
||||
bkp_dev bkp = {
|
||||
.regs = BKP_BASE,
|
||||
};
|
||||
/** Backup device. */
|
||||
const bkp_dev *BKP = &bkp;
|
||||
|
||||
/**
|
||||
* @brief Initialize backup interface.
|
||||
*
|
||||
* Enables the power and backup interface clocks, and resets the
|
||||
* backup device.
|
||||
*/
|
||||
void bkp_init(void) {
|
||||
/* Don't call pwr_init(), or you'll reset the device. We just
|
||||
* need the clock. */
|
||||
rcc_clk_enable(RCC_PWR);
|
||||
rcc_clk_enable(RCC_BKP);
|
||||
rcc_reset_dev(RCC_BKP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable write access to the backup registers. Backup interface must
|
||||
* be initialized for subsequent register writes to work.
|
||||
* @see bkp_init()
|
||||
*/
|
||||
void bkp_enable_writes(void) {
|
||||
*bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable write access to the backup registers.
|
||||
*/
|
||||
void bkp_disable_writes(void) {
|
||||
*bb_perip(&PWR_BASE->CR, PWR_CR_DBP_BIT) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a value from given backup data register.
|
||||
* @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on
|
||||
* medium-density devices, 42 on high-density devices).
|
||||
*/
|
||||
uint16 bkp_read(uint8 reg) {
|
||||
__io uint32* dr = data_register(reg);
|
||||
if (!dr) {
|
||||
ASSERT(0); /* nonexistent register */
|
||||
return 0;
|
||||
}
|
||||
return (uint16)*dr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a value to given data register.
|
||||
*
|
||||
* Write access to backup registers must be enabled.
|
||||
*
|
||||
* @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10
|
||||
* on medium-density devices, 42 on high-density devices).
|
||||
* @param val Value to write into the register.
|
||||
* @see bkp_enable_writes()
|
||||
*/
|
||||
void bkp_write(uint8 reg, uint16 val) {
|
||||
__io uint32* dr = data_register(reg);
|
||||
if (!dr) {
|
||||
ASSERT(0); /* nonexistent register */
|
||||
return;
|
||||
}
|
||||
*dr = (uint32)val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data register memory layout is not contiguous. It's split up from
|
||||
* 1--NR_LOW_DRS, beginning at BKP_BASE->DR1, through to
|
||||
* (NR_LOW_DRS+1)--BKP_NR_DATA_REGS, beginning at BKP_BASE->DR11.
|
||||
*/
|
||||
#define NR_LOW_DRS 10
|
||||
|
||||
static inline __io uint32* data_register(uint8 reg) {
|
||||
if (reg < 1 || reg > BKP_NR_DATA_REGS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if BKP_NR_DATA_REGS == NR_LOW_DRS
|
||||
return (uint32*)BKP_BASE + reg;
|
||||
#else
|
||||
if (reg <= NR_LOW_DRS) {
|
||||
return (uint32*)BKP_BASE + reg;
|
||||
} else {
|
||||
return (uint32*)&(BKP_BASE->DR11) + (reg - NR_LOW_DRS - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
120
BootLoaders/Boards/stm32/cores/maple/libmaple/dac.c
Normal file
120
BootLoaders/Boards/stm32/cores/maple/libmaple/dac.c
Normal file
@ -0,0 +1,120 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Bryan Newbold.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/dac.c
|
||||
* @brief Digital to analog converter support.
|
||||
*/
|
||||
|
||||
#include <libmaple/dac.h>
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/gpio.h>
|
||||
|
||||
#if STM32_HAVE_DAC
|
||||
dac_dev dac = {
|
||||
.regs = DAC_BASE,
|
||||
};
|
||||
const dac_dev *DAC = &dac;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize the digital to analog converter
|
||||
* @param dev DAC device
|
||||
* @param flags Flags:
|
||||
* DAC_CH1: Enable channel 1
|
||||
* DAC_CH2: Enable channel 2
|
||||
* @sideeffect May set PA4 or PA5 to INPUT_ANALOG
|
||||
*/
|
||||
void dac_init(const dac_dev *dev, uint32 flags) {
|
||||
/* First turn on the clock */
|
||||
rcc_clk_enable(RCC_DAC);
|
||||
rcc_reset_dev(RCC_DAC);
|
||||
|
||||
if (flags & DAC_CH1) {
|
||||
dac_enable_channel(dev, 1);
|
||||
}
|
||||
|
||||
if (flags & DAC_CH2) {
|
||||
dac_enable_channel(dev, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a 12-bit value to the DAC to output
|
||||
* @param dev DAC device
|
||||
* @param channel channel to select (1 or 2)
|
||||
* @param val value to write
|
||||
*/
|
||||
void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) {
|
||||
switch(channel) {
|
||||
case 1:
|
||||
dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val;
|
||||
break;
|
||||
case 2:
|
||||
dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a DAC channel
|
||||
* @param dev DAC device
|
||||
* @param channel channel to enable, either 1 or 2
|
||||
* @sideeffect May change pin mode of PA4 or PA5
|
||||
*/
|
||||
void dac_enable_channel(const dac_dev *dev, uint8 channel) {
|
||||
/*
|
||||
* Setup ANALOG mode on PA4 and PA5. This mapping is consistent
|
||||
* across all supported STM32s with a DAC.
|
||||
*/
|
||||
switch (channel) {
|
||||
case 1:
|
||||
gpio_set_mode(GPIOA, 4, GPIO_MODE_ANALOG);
|
||||
dev->regs->CR |= DAC_CR_EN1;
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_mode(GPIOA, 5, GPIO_MODE_ANALOG);
|
||||
dev->regs->CR |= DAC_CR_EN2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a DAC channel
|
||||
* @param dev DAC device
|
||||
* @param channel channel to disable, either 1 or 2
|
||||
*/
|
||||
void dac_disable_channel(const dac_dev *dev, uint8 channel) {
|
||||
switch (channel) {
|
||||
case 1:
|
||||
dev->regs->CR &= ~DAC_CR_EN1;
|
||||
break;
|
||||
case 2:
|
||||
dev->regs->CR &= ~DAC_CR_EN2;
|
||||
break;
|
||||
}
|
||||
}
|
82
BootLoaders/Boards/stm32/cores/maple/libmaple/dma.c
Normal file
82
BootLoaders/Boards/stm32/cores/maple/libmaple/dma.c
Normal file
@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Michael Hope.
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/dma.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
||||
* Original implementation by Michael Hope
|
||||
* @brief Portable DMA routines.
|
||||
*/
|
||||
|
||||
#include <libmaple/dma.h>
|
||||
#include "dma_private.h"
|
||||
#include "stm32_private.h"
|
||||
|
||||
/*
|
||||
* Convenience routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize a DMA device.
|
||||
* @param dev Device to initialize.
|
||||
*/
|
||||
void dma_init(dma_dev *dev) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Private API
|
||||
*/
|
||||
|
||||
enum dma_atype _dma_addr_type(__io void *addr) {
|
||||
switch (stm32_block_purpose((void*)addr)) {
|
||||
/* Notice we're treating the code block as memory here. That's
|
||||
* correct for addresses in Flash and in [0x0, 0x7FFFFFF]
|
||||
* (provided that those addresses are aliased to Flash, SRAM, or
|
||||
* FSMC, depending on BOOT[01] and possibly SYSCFG_MEMRMP). It's
|
||||
* not correct for other addresses in the code block, but those
|
||||
* will (hopefully) just fail-fast with transfer or bus errors. If
|
||||
* lots of people get confused, it might be worth being more
|
||||
* careful here. */
|
||||
case STM32_BLOCK_CODE: /* Fall through */
|
||||
case STM32_BLOCK_SRAM: /* ... */
|
||||
case STM32_BLOCK_FSMC_1_2: /* ... */
|
||||
case STM32_BLOCK_FSMC_3_4:
|
||||
return DMA_ATYPE_MEM;
|
||||
case STM32_BLOCK_PERIPH:
|
||||
return DMA_ATYPE_PER;
|
||||
case STM32_BLOCK_FSMC_REG: /* Fall through */
|
||||
/* Is this right? I can't think of a reason to DMA into or out
|
||||
* of the FSMC registers. [mbolivar] */
|
||||
case STM32_BLOCK_UNUSED: /* ... */
|
||||
case STM32_BLOCK_CORTEX_INTERNAL: /* ... */
|
||||
return DMA_ATYPE_OTHER;
|
||||
default:
|
||||
ASSERT(0); /* Can't happen */
|
||||
return DMA_ATYPE_OTHER;
|
||||
}
|
||||
}
|
412
BootLoaders/Boards/stm32/cores/maple/libmaple/dma_f1.c
Normal file
412
BootLoaders/Boards/stm32/cores/maple/libmaple/dma_f1.c
Normal file
@ -0,0 +1,412 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Michael Hope.
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/dma.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
||||
* Original implementation by Michael Hope
|
||||
* @brief STM32F1 DMA support.
|
||||
*/
|
||||
|
||||
#include <libmaple/dma.h>
|
||||
#include <libmaple/bitband.h>
|
||||
|
||||
/* Hack to ensure inlining in dma_irq_handler() */
|
||||
#define DMA_GET_HANDLER(dev, tube) (dev->handlers[tube - 1].handler)
|
||||
#include "dma_private.h"
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
static dma_dev dma1 = {
|
||||
.regs = DMA1_BASE,
|
||||
.clk_id = RCC_DMA1,
|
||||
.handlers = {{ .handler = NULL, .irq_line = NVIC_DMA_CH1 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH2 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH3 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH4 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH5 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH6 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA_CH7 }},
|
||||
};
|
||||
/** STM32F1 DMA1 device */
|
||||
dma_dev *DMA1 = &dma1;
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
static dma_dev dma2 = {
|
||||
.regs = DMA2_BASE,
|
||||
.clk_id = RCC_DMA2,
|
||||
.handlers = {{ .handler = NULL, .irq_line = NVIC_DMA2_CH1 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA2_CH2 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA2_CH3 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 },
|
||||
{ .handler = NULL, .irq_line = NVIC_DMA2_CH_4_5 }}, /* !@#$ */
|
||||
};
|
||||
/** STM32F1 DMA2 device */
|
||||
dma_dev *DMA2 = &dma2;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Auxiliary routines
|
||||
*/
|
||||
|
||||
/* Can channel serve cfg->tube_req_src? */
|
||||
static int cfg_req_ok(dma_channel channel, dma_tube_config *cfg) {
|
||||
return (cfg->tube_req_src & 0x7) == channel;
|
||||
}
|
||||
|
||||
/* Can dev serve cfg->tube_req_src? */
|
||||
static int cfg_dev_ok(dma_dev *dev, dma_tube_config *cfg) {
|
||||
return (rcc_clk_id)(cfg->tube_req_src >> 3) == dev->clk_id;
|
||||
}
|
||||
|
||||
/* Is addr acceptable for use as DMA src/dst? */
|
||||
static int cfg_mem_ok(__io void *addr) {
|
||||
enum dma_atype atype = _dma_addr_type(addr);
|
||||
return atype == DMA_ATYPE_MEM || atype == DMA_ATYPE_PER;
|
||||
}
|
||||
|
||||
/* Is the direction implied by src->dst supported? */
|
||||
static int cfg_dir_ok(dma_tube_config *cfg) {
|
||||
/* We can't do peripheral->peripheral transfers. */
|
||||
return ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) ||
|
||||
(_dma_addr_type(cfg->tube_dst) == DMA_ATYPE_MEM));
|
||||
}
|
||||
|
||||
static int preconfig_check(dma_dev *dev, dma_channel channel,
|
||||
dma_tube_config *cfg) {
|
||||
if (!cfg_req_ok(channel, cfg)) {
|
||||
return -DMA_TUBE_CFG_EREQ;
|
||||
}
|
||||
if (cfg->tube_nr_xfers > 65535) {
|
||||
return -DMA_TUBE_CFG_ENDATA;
|
||||
}
|
||||
if (!cfg_dev_ok(dev, cfg)) {
|
||||
return -DMA_TUBE_CFG_EDEV;
|
||||
}
|
||||
if (!cfg_mem_ok(cfg->tube_src)) {
|
||||
return -DMA_TUBE_CFG_ESRC;
|
||||
}
|
||||
if (!cfg_mem_ok(cfg->tube_dst)) {
|
||||
return -DMA_TUBE_CFG_EDST;
|
||||
}
|
||||
if (!cfg_dir_ok(cfg)) {
|
||||
return -DMA_TUBE_CFG_EDIR;
|
||||
}
|
||||
return DMA_TUBE_CFG_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void set_ccr(dma_tube_reg_map *chregs,
|
||||
dma_xfer_size msize, int minc,
|
||||
dma_xfer_size psize, int pinc,
|
||||
uint32 other_flags) {
|
||||
chregs->CCR = ((msize << 10) | (psize << 8) |
|
||||
(minc ? DMA_CCR_MINC : 0) | (pinc ? DMA_CCR_PINC : 0) |
|
||||
other_flags);
|
||||
}
|
||||
|
||||
static inline uint32 cfg_ccr_flags(unsigned tube_flags) {
|
||||
/* DMA_CFG_SRC_INC and DMA_CFG_DST_INC are special */
|
||||
return tube_flags & ~(DMA_CFG_SRC_INC | DMA_CFG_DST_INC);
|
||||
}
|
||||
|
||||
/* Configure chregs according to cfg, where cfg->tube_dst is peripheral. */
|
||||
static int config_to_per(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
|
||||
/* Check that ->tube_src is memory (if it's anything else, we
|
||||
* shouldn't have been called). */
|
||||
ASSERT(_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM);
|
||||
|
||||
set_ccr(chregs,
|
||||
cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
|
||||
cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
|
||||
(cfg_ccr_flags(cfg->tube_flags) | DMA_CCR_DIR_FROM_MEM));
|
||||
chregs->CNDTR = cfg->tube_nr_xfers;
|
||||
chregs->CMAR = (uint32)cfg->tube_src;
|
||||
chregs->CPAR = (uint32)cfg->tube_dst;
|
||||
return DMA_TUBE_CFG_SUCCESS;
|
||||
}
|
||||
|
||||
/* Configure chregs according to cfg, where cfg->tube_dst is memory. */
|
||||
static int config_to_mem(dma_tube_reg_map *chregs, dma_tube_config *cfg) {
|
||||
uint32 mem2mem;
|
||||
|
||||
if ((_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM) &&
|
||||
(cfg->tube_flags & DMA_CFG_CIRC)) {
|
||||
/* Can't do mem-to-mem and circular mode */
|
||||
return -DMA_TUBE_CFG_ECFG;
|
||||
}
|
||||
|
||||
mem2mem = (_dma_addr_type(cfg->tube_src) == DMA_ATYPE_MEM ?
|
||||
DMA_CCR_MEM2MEM : 0);
|
||||
set_ccr(chregs,
|
||||
cfg->tube_dst_size, cfg->tube_flags & DMA_CFG_DST_INC,
|
||||
cfg->tube_src_size, cfg->tube_flags & DMA_CFG_SRC_INC,
|
||||
(cfg_ccr_flags(cfg->tube_flags) |
|
||||
DMA_CCR_DIR_FROM_PER |
|
||||
mem2mem));
|
||||
chregs->CNDTR = cfg->tube_nr_xfers;
|
||||
chregs->CMAR = (uint32)cfg->tube_dst;
|
||||
chregs->CPAR = (uint32)cfg->tube_src;
|
||||
return DMA_TUBE_CFG_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
int dma_tube_cfg(dma_dev *dev, dma_channel channel, dma_tube_config *cfg) {
|
||||
dma_tube_reg_map *chregs;
|
||||
int ret = preconfig_check(dev, channel, cfg);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
dma_disable(dev, channel); /* Must disable before reconfiguring */
|
||||
dma_clear_isr_bits(dev, channel); /* For sanity and consistency
|
||||
* with STM32F2. */
|
||||
|
||||
chregs = dma_tube_regs(dev, channel);
|
||||
switch (_dma_addr_type(cfg->tube_dst)) {
|
||||
case DMA_ATYPE_PER:
|
||||
ret = config_to_per(chregs, cfg);
|
||||
break;
|
||||
case DMA_ATYPE_MEM:
|
||||
ret = config_to_mem(chregs, cfg);
|
||||
break;
|
||||
default:
|
||||
/* Can't happen */
|
||||
ASSERT(0);
|
||||
return -DMA_TUBE_CFG_ECFG;
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
chregs->CNDTR = cfg->tube_nr_xfers;
|
||||
return DMA_TUBE_CFG_SUCCESS;
|
||||
}
|
||||
|
||||
void dma_set_priority(dma_dev *dev,
|
||||
dma_channel channel,
|
||||
dma_priority priority) {
|
||||
dma_channel_reg_map *channel_regs;
|
||||
uint32 ccr;
|
||||
|
||||
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
|
||||
|
||||
channel_regs = dma_channel_regs(dev, channel);
|
||||
ccr = channel_regs->CCR;
|
||||
ccr &= ~DMA_CCR_PL;
|
||||
ccr |= (priority << 12);
|
||||
channel_regs->CCR = ccr;
|
||||
}
|
||||
|
||||
void dma_set_num_transfers(dma_dev *dev,
|
||||
dma_channel channel,
|
||||
uint16 num_transfers) {
|
||||
dma_channel_reg_map *channel_regs;
|
||||
|
||||
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
|
||||
|
||||
channel_regs = dma_channel_regs(dev, channel);
|
||||
channel_regs->CNDTR = num_transfers;
|
||||
}
|
||||
|
||||
void dma_attach_interrupt(dma_dev *dev, dma_channel channel,
|
||||
void (*handler)(void)) {
|
||||
DMA_GET_HANDLER(dev, channel) = handler;
|
||||
nvic_irq_enable(dev->handlers[channel - 1].irq_line);
|
||||
}
|
||||
|
||||
void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
|
||||
/* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
|
||||
dma_channel_regs(dev, channel)->CCR &= ~0xF;
|
||||
DMA_GET_HANDLER(dev, channel) = NULL;
|
||||
}
|
||||
|
||||
void dma_enable(dma_dev *dev, dma_channel channel) {
|
||||
dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
|
||||
bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 1);
|
||||
}
|
||||
|
||||
void dma_disable(dma_dev *dev, dma_channel channel) {
|
||||
dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
|
||||
bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0);
|
||||
}
|
||||
|
||||
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
|
||||
/* Grab and clear the ISR bits. */
|
||||
uint8 status_bits = dma_get_isr_bits(dev, channel);
|
||||
dma_clear_isr_bits(dev, channel);
|
||||
|
||||
/* If the channel global interrupt flag is cleared, then
|
||||
* something's very wrong. */
|
||||
ASSERT(status_bits & 0x1);
|
||||
/* If GIF is set, then some other flag should be set, barring
|
||||
* something unexpected (e.g. the user making an unforeseen IFCR
|
||||
* write). */
|
||||
ASSERT(status_bits != 0x1);
|
||||
|
||||
/* ISR flags get set even if the corresponding interrupt enable
|
||||
* bits in the channel's configuration register are cleared, so we
|
||||
* can't use a switch here.
|
||||
*
|
||||
* Don't change the order of these if statements. */
|
||||
if (status_bits & 0x8) {
|
||||
return DMA_TRANSFER_ERROR;
|
||||
} else if (status_bits & 0x2) {
|
||||
return DMA_TRANSFER_COMPLETE;
|
||||
} else if (status_bits & 0x4) {
|
||||
return DMA_TRANSFER_HALF_COMPLETE;
|
||||
}
|
||||
|
||||
/* If we get here, one of our assumptions has been violated, but
|
||||
* the debug level is too low for the above ASSERTs() to have had
|
||||
* any effect. In order to fail fast, mimic the DMA controller's
|
||||
* behavior when an error occurs. */
|
||||
dma_disable(dev, channel);
|
||||
return DMA_TRANSFER_ERROR;
|
||||
}
|
||||
|
||||
void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
|
||||
dma_channel_reg_map *chan_regs;
|
||||
|
||||
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
|
||||
|
||||
chan_regs = dma_channel_regs(dev, channel);
|
||||
chan_regs->CMAR = (uint32)addr;
|
||||
}
|
||||
|
||||
void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
|
||||
dma_channel_reg_map *chan_regs;
|
||||
|
||||
ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));
|
||||
|
||||
chan_regs = dma_channel_regs(dev, channel);
|
||||
chan_regs->CPAR = (uint32)addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deprecated. Use dma_tube_cfg() instead.
|
||||
*
|
||||
* Set up a DMA transfer.
|
||||
*
|
||||
* The channel will be disabled before being reconfigured. The
|
||||
* transfer will have low priority by default. You may choose another
|
||||
* priority before the transfer begins using dma_set_priority(), as
|
||||
* well as performing any other configuration you desire. When the
|
||||
* channel is configured to your liking, enable it using dma_enable().
|
||||
*
|
||||
* @param dev DMA device.
|
||||
* @param channel DMA channel.
|
||||
* @param peripheral_address Base address of peripheral data register
|
||||
* involved in the transfer.
|
||||
* @param peripheral_size Peripheral data transfer size.
|
||||
* @param memory_address Base memory address involved in the transfer.
|
||||
* @param memory_size Memory data transfer size.
|
||||
* @param mode Logical OR of dma_mode_flags
|
||||
*
|
||||
* @see dma_tube_cfg()
|
||||
*
|
||||
* @sideeffect Disables the given DMA channel.
|
||||
* @see dma_xfer_size
|
||||
* @see dma_mode_flags
|
||||
* @see dma_set_num_transfers()
|
||||
* @see dma_set_priority()
|
||||
* @see dma_attach_interrupt()
|
||||
* @see dma_enable()
|
||||
*/
|
||||
void dma_setup_transfer(dma_dev *dev,
|
||||
dma_channel channel,
|
||||
__io void *peripheral_address,
|
||||
dma_xfer_size peripheral_size,
|
||||
__io void *memory_address,
|
||||
dma_xfer_size memory_size,
|
||||
uint32 mode) {
|
||||
dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel);
|
||||
|
||||
dma_disable(dev, channel); /* can't write to CMAR/CPAR otherwise */
|
||||
channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode;
|
||||
channel_regs->CMAR = (uint32)memory_address;
|
||||
channel_regs->CPAR = (uint32)peripheral_address;
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ handlers
|
||||
*/
|
||||
|
||||
void __irq_dma1_channel1(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH1);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel2(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH2);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel3(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH3);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel4(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH4);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel5(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH5);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel6(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH6);
|
||||
}
|
||||
|
||||
void __irq_dma1_channel7(void) {
|
||||
dma_irq_handler(DMA1, DMA_CH7);
|
||||
}
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
void __irq_dma2_channel1(void) {
|
||||
dma_irq_handler(DMA2, DMA_CH1);
|
||||
}
|
||||
|
||||
void __irq_dma2_channel2(void) {
|
||||
dma_irq_handler(DMA2, DMA_CH2);
|
||||
}
|
||||
|
||||
void __irq_dma2_channel3(void) {
|
||||
dma_irq_handler(DMA2, DMA_CH3);
|
||||
}
|
||||
|
||||
void __irq_dma2_channel4_5(void) {
|
||||
if ((DMA2_BASE->CCR4 & DMA_CCR_EN) && (DMA2_BASE->ISR & DMA_ISR_GIF4)) {
|
||||
dma_irq_handler(DMA2, DMA_CH4);
|
||||
}
|
||||
if ((DMA2_BASE->CCR5 & DMA_CCR_EN) && (DMA2_BASE->ISR & DMA_ISR_GIF5)) {
|
||||
dma_irq_handler(DMA2, DMA_CH5);
|
||||
}
|
||||
}
|
||||
#endif
|
101
BootLoaders/Boards/stm32/cores/maple/libmaple/exc.S
Normal file
101
BootLoaders/Boards/stm32/cores/maple/libmaple/exc.S
Normal file
@ -0,0 +1,101 @@
|
||||
/* *****************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* ****************************************************************************/
|
||||
|
||||
# On an exception, push a fake stack thread mode stack frame and redirect
|
||||
# thread execution to a thread mode error handler
|
||||
|
||||
# From RM008:
|
||||
# The SP is decremented by eight words by the completion of the stack push.
|
||||
# Figure 5-1 shows the contents of the stack after an exception pre-empts the
|
||||
# current program flow.
|
||||
#
|
||||
# Old SP--> <previous>
|
||||
# xPSR
|
||||
# PC
|
||||
# LR
|
||||
# r12
|
||||
# r3
|
||||
# r2
|
||||
# r1
|
||||
# SP--> r0
|
||||
|
||||
.text
|
||||
.globl __exc_hardfault
|
||||
.globl __exc_nmi
|
||||
.globl __exc_hardfault
|
||||
.globl __exc_memmanage
|
||||
.globl __exc_busfault
|
||||
.globl __exc_usagefault
|
||||
|
||||
.code 16
|
||||
.thumb_func
|
||||
__exc_nmi:
|
||||
mov r0, #1
|
||||
b __default_exc
|
||||
|
||||
.thumb_func
|
||||
__exc_hardfault:
|
||||
mov r0, #2
|
||||
b __default_exc
|
||||
|
||||
.thumb_func
|
||||
__exc_memmanage:
|
||||
mov r0, #3
|
||||
b __default_exc
|
||||
|
||||
.thumb_func
|
||||
__exc_busfault:
|
||||
mov r0, #4
|
||||
b __default_exc
|
||||
|
||||
.thumb_func
|
||||
__exc_usagefault:
|
||||
mov r0, #5
|
||||
b __default_exc
|
||||
|
||||
.thumb_func
|
||||
__default_exc:
|
||||
ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are
|
||||
mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA.
|
||||
str r1, [r2]
|
||||
cpsid i @ Disable global interrupts
|
||||
ldr r2, SYSTICK_CSR @ Disable systick handler
|
||||
mov r1, #0
|
||||
str r1, [r2]
|
||||
ldr r1, CPSR_MASK @ Set default CPSR
|
||||
push {r1}
|
||||
ldr r1, TARGET_PC @ Set target pc
|
||||
push {r1}
|
||||
sub sp, sp, #24 @ Don't care
|
||||
ldr r1, EXC_RETURN @ Return to thread mode
|
||||
mov lr, r1
|
||||
bx lr @ Exception exit
|
||||
|
||||
.align 4
|
||||
CPSR_MASK: .word 0x61000000
|
||||
EXC_RETURN: .word 0xFFFFFFF9
|
||||
TARGET_PC: .word __error
|
||||
NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register
|
||||
SYSTICK_CSR: .word 0xE000E010 @ Systick control register
|
||||
|
292
BootLoaders/Boards/stm32/cores/maple/libmaple/exti.c
Normal file
292
BootLoaders/Boards/stm32/cores/maple/libmaple/exti.c
Normal file
@ -0,0 +1,292 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/exti.c
|
||||
* @brief External interrupt control routines
|
||||
*/
|
||||
|
||||
#include <libmaple/exti.h>
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/bitband.h>
|
||||
|
||||
static inline void dispatch_single_exti(uint32 exti_num);
|
||||
static inline void dispatch_extis(uint32 start, uint32 stop);
|
||||
|
||||
/*
|
||||
* Internal state
|
||||
*/
|
||||
|
||||
typedef struct exti_channel {
|
||||
void (*handler)(void *);
|
||||
void *arg;
|
||||
} exti_channel;
|
||||
|
||||
static exti_channel exti_channels[] = {
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI0
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI1
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI2
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI3
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI4
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI5
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI6
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI7
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI8
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI9
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI10
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI11
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI12
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI13
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI14
|
||||
{ .handler = NULL, .arg = NULL }, // EXTI15
|
||||
};
|
||||
|
||||
/*
|
||||
* Portable routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Register a handler to run upon external interrupt.
|
||||
*
|
||||
* This function assumes that the interrupt request corresponding to
|
||||
* the given external interrupt is masked.
|
||||
*
|
||||
* @param num External interrupt line number.
|
||||
* @param port Port to use as source input for external interrupt.
|
||||
* @param handler Function handler to execute when interrupt is triggered.
|
||||
* @param mode Type of transition to trigger on, one of:
|
||||
* EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
|
||||
* @see exti_num
|
||||
* @see exti_cfg
|
||||
* @see voidFuncPtr
|
||||
* @see exti_trigger_mode
|
||||
*/
|
||||
void exti_attach_interrupt(exti_num num,
|
||||
exti_cfg port,
|
||||
voidFuncPtr handler,
|
||||
exti_trigger_mode mode) {
|
||||
// Call callback version with arg being null
|
||||
exti_attach_callback(num, port, (voidArgumentFuncPtr)handler, NULL, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a handler with an argument to run upon external interrupt.
|
||||
*
|
||||
* This function assumes that the interrupt request corresponding to
|
||||
* the given external interrupt is masked.
|
||||
*
|
||||
* @param num External interrupt line number.
|
||||
* @param port Port to use as source input for external interrupt.
|
||||
* @param handler Function handler to execute when interrupt is triggered.
|
||||
* @param arg Argument to pass to the interrupt handler.
|
||||
* @param mode Type of transition to trigger on, one of:
|
||||
* EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING.
|
||||
* @see exti_num
|
||||
* @see exti_cfg
|
||||
* @see voidFuncPtr
|
||||
* @see exti_trigger_mode
|
||||
*/
|
||||
void exti_attach_callback(exti_num num,
|
||||
exti_cfg port,
|
||||
voidArgumentFuncPtr handler,
|
||||
void *arg,
|
||||
exti_trigger_mode mode) {
|
||||
ASSERT(handler);
|
||||
|
||||
/* Register the handler */
|
||||
exti_channels[num].handler = handler;
|
||||
exti_channels[num].arg = arg;
|
||||
|
||||
/* Set trigger mode */
|
||||
switch (mode) {
|
||||
case EXTI_RISING:
|
||||
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1);
|
||||
break;
|
||||
case EXTI_FALLING:
|
||||
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1);
|
||||
break;
|
||||
case EXTI_RISING_FALLING:
|
||||
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 1);
|
||||
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Use the chip-specific exti_select() to map num to port */
|
||||
exti_select(num, port);
|
||||
|
||||
/* Unmask external interrupt request */
|
||||
bb_peri_set_bit(&EXTI_BASE->IMR, num, 1);
|
||||
|
||||
/* Enable the interrupt line */
|
||||
switch(num)
|
||||
{
|
||||
case EXTI0:
|
||||
nvic_irq_enable(NVIC_EXTI0);
|
||||
break;
|
||||
case EXTI1:
|
||||
nvic_irq_enable(NVIC_EXTI1);
|
||||
break;
|
||||
case EXTI2:
|
||||
nvic_irq_enable(NVIC_EXTI2);
|
||||
break;
|
||||
case EXTI3:
|
||||
nvic_irq_enable(NVIC_EXTI3);
|
||||
break;
|
||||
case EXTI4:
|
||||
nvic_irq_enable(NVIC_EXTI4);
|
||||
break;
|
||||
case EXTI5:
|
||||
case EXTI6:
|
||||
case EXTI7:
|
||||
case EXTI8:
|
||||
case EXTI9:
|
||||
nvic_irq_enable(NVIC_EXTI_9_5);
|
||||
break;
|
||||
case EXTI10:
|
||||
case EXTI11:
|
||||
case EXTI12:
|
||||
case EXTI13:
|
||||
case EXTI14:
|
||||
case EXTI15:
|
||||
nvic_irq_enable(NVIC_EXTI_15_10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister an external interrupt handler
|
||||
* @param num External interrupt line to disable.
|
||||
* @see exti_num
|
||||
*/
|
||||
void exti_detach_interrupt(exti_num num) {
|
||||
/* First, mask the interrupt request */
|
||||
bb_peri_set_bit(&EXTI_BASE->IMR, num, 0);
|
||||
|
||||
/* Then, clear the trigger selection registers */
|
||||
bb_peri_set_bit(&EXTI_BASE->FTSR, num, 0);
|
||||
bb_peri_set_bit(&EXTI_BASE->RTSR, num, 0);
|
||||
|
||||
/* Finally, unregister the user's handler */
|
||||
exti_channels[num].handler = NULL;
|
||||
exti_channels[num].arg = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Private routines
|
||||
*/
|
||||
|
||||
void exti_do_select(__io uint32 *exti_cr, exti_num num, exti_cfg port) {
|
||||
uint32 shift = 4 * (num % 4);
|
||||
uint32 cr = *exti_cr;
|
||||
cr &= ~(0xF << shift);
|
||||
cr |= port << shift;
|
||||
*exti_cr = cr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handlers
|
||||
*/
|
||||
|
||||
void __irq_exti0(void) {
|
||||
dispatch_single_exti(EXTI0);
|
||||
}
|
||||
|
||||
void __irq_exti1(void) {
|
||||
dispatch_single_exti(EXTI1);
|
||||
}
|
||||
|
||||
void __irq_exti2(void) {
|
||||
dispatch_single_exti(EXTI2);
|
||||
}
|
||||
|
||||
void __irq_exti3(void) {
|
||||
dispatch_single_exti(EXTI3);
|
||||
}
|
||||
|
||||
void __irq_exti4(void) {
|
||||
dispatch_single_exti(EXTI4);
|
||||
}
|
||||
|
||||
void __irq_exti9_5(void) {
|
||||
dispatch_extis(5, 9);
|
||||
}
|
||||
|
||||
void __irq_exti15_10(void) {
|
||||
dispatch_extis(10, 15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary functions
|
||||
*/
|
||||
|
||||
/* Clear the pending bits for EXTIs whose bits are set in exti_msk.
|
||||
*
|
||||
* If a pending bit is cleared as the last instruction in an ISR, it
|
||||
* won't actually be cleared in time and the ISR will fire again. To
|
||||
* compensate, this function NOPs for 2 cycles after clearing the
|
||||
* pending bits to ensure it takes effect. */
|
||||
static inline __always_inline void clear_pending_msk(uint32 exti_msk) {
|
||||
EXTI_BASE->PR = exti_msk;
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
}
|
||||
|
||||
/* This dispatch routine is for non-multiplexed EXTI lines only; i.e.,
|
||||
* it doesn't check EXTI_PR. */
|
||||
static inline __always_inline void dispatch_single_exti(uint32 exti) {
|
||||
voidArgumentFuncPtr handler = exti_channels[exti].handler;
|
||||
|
||||
if (!handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
handler(exti_channels[exti].arg);
|
||||
clear_pending_msk(1U << exti);
|
||||
}
|
||||
|
||||
/* Dispatch routine for EXTIs which share an IRQ. */
|
||||
static inline __always_inline void dispatch_extis(uint32 start, uint32 stop) {
|
||||
uint32 pr = EXTI_BASE->PR;
|
||||
uint32 handled_msk = 0;
|
||||
uint32 exti;
|
||||
|
||||
/* Dispatch user handlers for pending EXTIs. */
|
||||
for (exti = start; exti <= stop; exti++) {
|
||||
uint32 eb = (1U << exti);
|
||||
if (pr & eb) {
|
||||
voidArgumentFuncPtr handler = exti_channels[exti].handler;
|
||||
if (handler) {
|
||||
handler(exti_channels[exti].arg);
|
||||
handled_msk |= eb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the pending bits for handled EXTIs. */
|
||||
clear_pending_msk(handled_msk);
|
||||
}
|
32
BootLoaders/Boards/stm32/cores/maple/libmaple/exti_f1.c
Normal file
32
BootLoaders/Boards/stm32/cores/maple/libmaple/exti_f1.c
Normal file
@ -0,0 +1,32 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
#include "exti_private.h"
|
||||
|
||||
void exti_select(exti_num num, exti_cfg port) {
|
||||
exti_do_select(&AFIO_BASE->EXTICR1 + num / 4, num, port);
|
||||
}
|
55
BootLoaders/Boards/stm32/cores/maple/libmaple/flash.c
Normal file
55
BootLoaders/Boards/stm32/cores/maple/libmaple/flash.c
Normal file
@ -0,0 +1,55 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/flash.c
|
||||
* @brief Flash management functions
|
||||
*/
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include <libmaple/flash.h>
|
||||
|
||||
/**
|
||||
* @brief Set flash wait states
|
||||
*
|
||||
* Note that not all wait states are available on every MCU. See the
|
||||
* Flash programming manual for your MCU for restrictions on the
|
||||
* allowed value of wait_states for a given system clock (SYSCLK)
|
||||
* frequency.
|
||||
*
|
||||
* @param wait_states number of wait states (one of
|
||||
* FLASH_WAIT_STATE_0, FLASH_WAIT_STATE_1,
|
||||
* ..., FLASH_WAIT_STATE_7).
|
||||
*/
|
||||
void flash_set_latency(uint32 wait_states) {
|
||||
uint32 val = FLASH_BASE->ACR;
|
||||
|
||||
val &= ~FLASH_ACR_LATENCY;
|
||||
val |= wait_states;
|
||||
|
||||
FLASH_BASE->ACR = val;
|
||||
}
|
95
BootLoaders/Boards/stm32/cores/maple/libmaple/fsmc_f1.c
Normal file
95
BootLoaders/Boards/stm32/cores/maple/libmaple/fsmc_f1.c
Normal file
@ -0,0 +1,95 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
* Copyright (c) 2010 Bryan Newbold.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/fsmc.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>,
|
||||
* Bryan Newbold <bnewbold@robocracy.org>
|
||||
* @brief STM32F1 FSMC support.
|
||||
*/
|
||||
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
#if STM32_HAVE_FSMC /* Don't try building the rest for MCUs without FSMC */
|
||||
|
||||
#include <libmaple/fsmc.h>
|
||||
#include <libmaple/gpio.h>
|
||||
|
||||
void fsmc_sram_init_gpios(void) {
|
||||
/* Data lines... */
|
||||
gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP);
|
||||
|
||||
/* Address lines... */
|
||||
gpio_set_mode(GPIOD, 11, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 12, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOD, 13, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP);
|
||||
|
||||
/* And control lines... */
|
||||
gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // NOE
|
||||
gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // NWE
|
||||
|
||||
gpio_set_mode(GPIOD, 7, GPIO_AF_OUTPUT_PP); // NE1
|
||||
gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2
|
||||
gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3
|
||||
gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4
|
||||
|
||||
gpio_set_mode(GPIOE, 0, GPIO_AF_OUTPUT_PP); // NBL0
|
||||
gpio_set_mode(GPIOE, 1, GPIO_AF_OUTPUT_PP); // NBL1
|
||||
}
|
||||
|
||||
#endif /* STM32_HAVE_FSMC */
|
50
BootLoaders/Boards/stm32/cores/maple/libmaple/gpio.c
Normal file
50
BootLoaders/Boards/stm32/cores/maple/libmaple/gpio.c
Normal file
@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/gpio.c
|
||||
* @brief Generic STM32 GPIO support.
|
||||
*/
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
/*
|
||||
* GPIO routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize a GPIO device.
|
||||
*
|
||||
* Enables the clock for and resets the given device.
|
||||
*
|
||||
* @param dev GPIO device to initialize.
|
||||
*/
|
||||
void gpio_init(gpio_dev *dev) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
rcc_reset_dev(dev->clk_id);
|
||||
}
|
182
BootLoaders/Boards/stm32/cores/maple/libmaple/gpio_f1.c
Normal file
182
BootLoaders/Boards/stm32/cores/maple/libmaple/gpio_f1.c
Normal file
@ -0,0 +1,182 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/gpio.c
|
||||
* @brief STM32F1 GPIO support.
|
||||
*/
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
/*
|
||||
* GPIO devices
|
||||
*/
|
||||
|
||||
gpio_dev gpioa = {
|
||||
.regs = GPIOA_BASE,
|
||||
.clk_id = RCC_GPIOA,
|
||||
.exti_port = EXTI_PA,
|
||||
};
|
||||
/** GPIO port A device. */
|
||||
gpio_dev* const GPIOA = &gpioa;
|
||||
|
||||
gpio_dev gpiob = {
|
||||
.regs = GPIOB_BASE,
|
||||
.clk_id = RCC_GPIOB,
|
||||
.exti_port = EXTI_PB,
|
||||
};
|
||||
/** GPIO port B device. */
|
||||
gpio_dev* const GPIOB = &gpiob;
|
||||
|
||||
gpio_dev gpioc = {
|
||||
.regs = GPIOC_BASE,
|
||||
.clk_id = RCC_GPIOC,
|
||||
.exti_port = EXTI_PC,
|
||||
};
|
||||
/** GPIO port C device. */
|
||||
gpio_dev* const GPIOC = &gpioc;
|
||||
|
||||
gpio_dev gpiod = {
|
||||
.regs = GPIOD_BASE,
|
||||
.clk_id = RCC_GPIOD,
|
||||
.exti_port = EXTI_PD,
|
||||
};
|
||||
/** GPIO port D device. */
|
||||
gpio_dev* const GPIOD = &gpiod;
|
||||
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
gpio_dev gpioe = {
|
||||
.regs = GPIOE_BASE,
|
||||
.clk_id = RCC_GPIOE,
|
||||
.exti_port = EXTI_PE,
|
||||
};
|
||||
/** GPIO port E device. */
|
||||
gpio_dev* const GPIOE = &gpioe;
|
||||
|
||||
gpio_dev gpiof = {
|
||||
.regs = GPIOF_BASE,
|
||||
.clk_id = RCC_GPIOF,
|
||||
.exti_port = EXTI_PF,
|
||||
};
|
||||
/** GPIO port F device. */
|
||||
gpio_dev* const GPIOF = &gpiof;
|
||||
|
||||
gpio_dev gpiog = {
|
||||
.regs = GPIOG_BASE,
|
||||
.clk_id = RCC_GPIOG,
|
||||
.exti_port = EXTI_PG,
|
||||
};
|
||||
/** GPIO port G device. */
|
||||
gpio_dev* const GPIOG = &gpiog;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GPIO routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize and reset all available GPIO devices.
|
||||
*/
|
||||
void gpio_init_all(void) {
|
||||
gpio_init(GPIOA);
|
||||
gpio_init(GPIOB);
|
||||
gpio_init(GPIOC);
|
||||
gpio_init(GPIOD);
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
gpio_init(GPIOE);
|
||||
gpio_init(GPIOF);
|
||||
gpio_init(GPIOG);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode of a GPIO pin.
|
||||
*
|
||||
* @param dev GPIO device.
|
||||
* @param pin Pin on the device whose mode to set, 0--15.
|
||||
* @param mode General purpose or alternate function mode to set the pin to.
|
||||
* @see gpio_pin_mode
|
||||
*/
|
||||
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
|
||||
gpio_reg_map *regs = dev->regs;
|
||||
__io uint32 *cr = ®s->CRL + (pin >> 3);
|
||||
uint32 shift = (pin & 0x7) * 4;
|
||||
uint32 tmp = *cr;
|
||||
|
||||
tmp &= ~(0xF << shift);
|
||||
tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift;
|
||||
*cr = tmp;
|
||||
|
||||
if (mode == GPIO_INPUT_PD) {
|
||||
regs->ODR &= ~(1U << pin);
|
||||
} else if (mode == GPIO_INPUT_PU) {
|
||||
regs->ODR |= (1U << pin);
|
||||
}
|
||||
}
|
||||
|
||||
gpio_pin_mode gpio_get_mode(gpio_dev *dev, uint8 pin) {
|
||||
gpio_reg_map *regs = dev->regs;
|
||||
__io uint32 *cr = ®s->CRL + (pin >> 3);
|
||||
uint32 shift = (pin & 0x7) * 4;
|
||||
|
||||
uint32 crMode = (*cr>>shift) & 0x0F;
|
||||
|
||||
// could be pull up or pull down. Nee to check the ODR
|
||||
if (crMode==GPIO_INPUT_PD && ((regs->ODR >> pin) & 0x01) !=0 )
|
||||
{
|
||||
crMode = GPIO_INPUT_PU;
|
||||
}
|
||||
|
||||
return(crMode);
|
||||
}
|
||||
|
||||
/*
|
||||
* AFIO
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the AFIO clock, and reset the AFIO registers.
|
||||
*/
|
||||
void afio_init(void) {
|
||||
rcc_clk_enable(RCC_AFIO);
|
||||
rcc_reset_dev(RCC_AFIO);
|
||||
}
|
||||
|
||||
#define AFIO_EXTI_SEL_MASK 0xF
|
||||
|
||||
/**
|
||||
* @brief Perform an alternate function remap.
|
||||
* @param remapping Remapping to perform.
|
||||
*/
|
||||
void afio_remap(afio_remap_peripheral remapping) {
|
||||
if (remapping & AFIO_REMAP_USE_MAPR2) {
|
||||
remapping &= ~AFIO_REMAP_USE_MAPR2;
|
||||
AFIO_BASE->MAPR2 |= remapping;
|
||||
} else {
|
||||
AFIO_BASE->MAPR |= remapping;
|
||||
}
|
||||
}
|
520
BootLoaders/Boards/stm32/cores/maple/libmaple/i2c.c
Normal file
520
BootLoaders/Boards/stm32/cores/maple/libmaple/i2c.c
Normal file
@ -0,0 +1,520 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/i2c.c
|
||||
* @author Perry Hung <perry@leaflabs.com>
|
||||
* @brief Inter-Integrated Circuit (I2C) support.
|
||||
*
|
||||
* Currently, only master mode is supported.
|
||||
*/
|
||||
|
||||
#include "i2c_private.h"
|
||||
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/rcc.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/i2c.h>
|
||||
#include <libmaple/systick.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static inline int32 wait_for_state_change(i2c_dev *dev,
|
||||
i2c_state state,
|
||||
uint32 timeout);
|
||||
static void set_ccr_trise(i2c_dev *dev, uint32 flags);
|
||||
|
||||
/**
|
||||
* @brief Fill data register with slave address
|
||||
* @param dev I2C device
|
||||
* @param addr Slave address
|
||||
* @param rw Read/write bit
|
||||
*/
|
||||
static inline void i2c_send_slave_addr(i2c_dev *dev, uint32 addr, uint32 rw) {
|
||||
dev->regs->DR = (addr << 1) | rw;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple debugging trail. Define I2C_DEBUG to turn on.
|
||||
*/
|
||||
#ifdef I2C_DEBUG
|
||||
|
||||
#define NR_CRUMBS 128
|
||||
static struct crumb crumbs[NR_CRUMBS];
|
||||
static uint32 cur_crumb = 0;
|
||||
|
||||
static inline void i2c_drop_crumb(uint32 event, uint32 arg0, uint32 arg1) {
|
||||
if (cur_crumb < NR_CRUMBS) {
|
||||
struct crumb *crumb = &crumbs[cur_crumb++];
|
||||
crumb->event = event;
|
||||
crumb->arg0 = arg0;
|
||||
crumb->arg1 = arg1;
|
||||
}
|
||||
}
|
||||
#define I2C_CRUMB(event, arg0, arg1) i2c_drop_crumb(event, arg0, arg1)
|
||||
|
||||
#else
|
||||
#define I2C_CRUMB(event, arg0, arg1)
|
||||
#endif
|
||||
|
||||
struct crumb {
|
||||
uint32 event;
|
||||
uint32 arg0;
|
||||
uint32 arg1;
|
||||
};
|
||||
|
||||
enum {
|
||||
IRQ_ENTRY = 1,
|
||||
TXE_ONLY = 2,
|
||||
TXE_BTF = 3,
|
||||
STOP_SENT = 4,
|
||||
TEST = 5,
|
||||
RX_ADDR_START = 6,
|
||||
RX_ADDR_STOP = 7,
|
||||
RXNE_ONLY = 8,
|
||||
RXNE_SENDING = 9,
|
||||
RXNE_START_SENT = 10,
|
||||
RXNE_STOP_SENT = 11,
|
||||
RXNE_DONE = 12,
|
||||
ERROR_ENTRY = 13,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Reset an I2C bus.
|
||||
*
|
||||
* Reset is accomplished by clocking out pulses until any hung slaves
|
||||
* release SDA and SCL, then generating a START condition, then a STOP
|
||||
* condition.
|
||||
*
|
||||
* @param dev I2C device
|
||||
*/
|
||||
void i2c_bus_reset(const i2c_dev *dev) {
|
||||
/* Release both lines */
|
||||
i2c_master_release_bus(dev);
|
||||
|
||||
/*
|
||||
* Make sure the bus is free by clocking it until any slaves release the
|
||||
* bus.
|
||||
*/
|
||||
while (!gpio_read_bit(sda_port(dev), dev->sda_pin)) {
|
||||
/* Wait for any clock stretching to finish */
|
||||
while (!gpio_read_bit(scl_port(dev), dev->scl_pin))
|
||||
;
|
||||
delay_us(10);
|
||||
|
||||
/* Pull low */
|
||||
gpio_write_bit(scl_port(dev), dev->scl_pin, 0);
|
||||
delay_us(10);
|
||||
|
||||
/* Release high again */
|
||||
gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
|
||||
delay_us(10);
|
||||
}
|
||||
|
||||
/* Generate start then stop condition */
|
||||
gpio_write_bit(sda_port(dev), dev->sda_pin, 0);
|
||||
delay_us(10);
|
||||
gpio_write_bit(scl_port(dev), dev->scl_pin, 0);
|
||||
delay_us(10);
|
||||
gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
|
||||
delay_us(10);
|
||||
gpio_write_bit(sda_port(dev), dev->sda_pin, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize an I2C device and reset its registers to their
|
||||
* default values.
|
||||
* @param dev Device to initialize.
|
||||
*/
|
||||
void i2c_init(i2c_dev *dev) {
|
||||
rcc_reset_dev(dev->clk_id);
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
}
|
||||
|
||||
/* Hack for deprecated bit of STM32F1 functionality */
|
||||
#ifndef _I2C_HAVE_DEPRECATED_I2C_REMAP
|
||||
#define _i2c_handle_remap(dev, flags) ((void)0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize an I2C device as bus master
|
||||
* @param dev Device to enable
|
||||
* @param flags Bitwise or of the following I2C options:
|
||||
* I2C_FAST_MODE: 400 khz operation,
|
||||
* I2C_DUTY_16_9: 16/9 Tlow/Thigh duty cycle (only applicable for
|
||||
* fast mode),
|
||||
* I2C_BUS_RESET: Reset the bus and clock out any hung slaves on
|
||||
* initialization,
|
||||
* I2C_10BIT_ADDRESSING: Enable 10-bit addressing,
|
||||
* I2C_REMAP: (deprecated, STM32F1 only) Remap I2C1 to SCL/PB8
|
||||
* SDA/PB9.
|
||||
*/
|
||||
void i2c_master_enable(i2c_dev *dev, uint32 flags) {
|
||||
/* PE must be disabled to configure the device */
|
||||
ASSERT(!(dev->regs->CR1 & I2C_CR1_PE));
|
||||
|
||||
/* Ugh */
|
||||
_i2c_handle_remap(dev, flags);
|
||||
|
||||
/* Reset the bus. Clock out any hung slaves. */
|
||||
if (flags & I2C_BUS_RESET) {
|
||||
i2c_bus_reset(dev);
|
||||
}
|
||||
|
||||
/* Turn on clock and set GPIO modes */
|
||||
i2c_init(dev);
|
||||
i2c_config_gpios(dev);
|
||||
|
||||
/* Configure clock and rise time */
|
||||
set_ccr_trise(dev, flags);
|
||||
|
||||
/* Enable event and buffer interrupts */
|
||||
nvic_irq_enable(dev->ev_nvic_line);
|
||||
nvic_irq_enable(dev->er_nvic_line);
|
||||
i2c_enable_irq(dev, I2C_IRQ_EVENT | I2C_IRQ_BUFFER | I2C_IRQ_ERROR);
|
||||
|
||||
/* Make it go! */
|
||||
i2c_peripheral_enable(dev);
|
||||
|
||||
dev->state = I2C_STATE_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process an i2c transaction.
|
||||
*
|
||||
* Transactions are composed of one or more i2c_msg's, and may be read
|
||||
* or write tranfers. Multiple i2c_msg's will generate a repeated
|
||||
* start in between messages.
|
||||
*
|
||||
* @param dev I2C device
|
||||
* @param msgs Messages to send/receive
|
||||
* @param num Number of messages to send/receive
|
||||
* @param timeout Bus idle timeout in milliseconds before aborting the
|
||||
* transfer. 0 denotes no timeout.
|
||||
* @return 0 on success,
|
||||
* I2C_ERROR_PROTOCOL if there was a protocol error,
|
||||
* I2C_ERROR_TIMEOUT if the transfer timed out.
|
||||
*/
|
||||
int32 i2c_master_xfer(i2c_dev *dev,
|
||||
i2c_msg *msgs,
|
||||
uint16 num,
|
||||
uint32 timeout) {
|
||||
int32 rc;
|
||||
|
||||
ASSERT(dev->state == I2C_STATE_IDLE);
|
||||
|
||||
dev->msg = msgs;
|
||||
dev->msgs_left = num;
|
||||
dev->timestamp = systick_uptime();
|
||||
dev->state = I2C_STATE_BUSY;
|
||||
|
||||
i2c_enable_irq(dev, I2C_IRQ_EVENT);
|
||||
i2c_start_condition(dev);
|
||||
|
||||
rc = wait_for_state_change(dev, I2C_STATE_XFER_DONE, timeout);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev->state = I2C_STATE_IDLE;
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for an I2C event, or time out in case of error.
|
||||
* @param dev I2C device
|
||||
* @param state I2C_state state to wait for
|
||||
* @param timeout Timeout, in milliseconds
|
||||
* @return 0 if target state is reached, a negative value on error.
|
||||
*/
|
||||
static inline int32 wait_for_state_change(i2c_dev *dev,
|
||||
i2c_state state,
|
||||
uint32 timeout) {
|
||||
i2c_state tmp;
|
||||
|
||||
while (1) {
|
||||
tmp = dev->state;
|
||||
|
||||
if (tmp == I2C_STATE_ERROR) {
|
||||
return I2C_STATE_ERROR;
|
||||
}
|
||||
|
||||
if (tmp == state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
if (systick_uptime() > (dev->timestamp + timeout)) {
|
||||
/* TODO: overflow? */
|
||||
/* TODO: racy? */
|
||||
return I2C_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Private API
|
||||
*/
|
||||
|
||||
/*
|
||||
* IRQ handler for I2C master. Handles transmission/reception.
|
||||
*/
|
||||
void _i2c_irq_handler(i2c_dev *dev) {
|
||||
/* WTFs:
|
||||
* - Where is I2C_MSG_10BIT_ADDR handled?
|
||||
*/
|
||||
i2c_msg *msg = dev->msg;
|
||||
|
||||
uint8 read = msg->flags & I2C_MSG_READ;
|
||||
|
||||
uint32 sr1 = dev->regs->SR1;
|
||||
uint32 sr2 = dev->regs->SR2;
|
||||
I2C_CRUMB(IRQ_ENTRY, sr1, sr2);
|
||||
|
||||
/*
|
||||
* Reset timeout counter
|
||||
*/
|
||||
dev->timestamp = systick_uptime();
|
||||
|
||||
/*
|
||||
* EV5: Start condition sent
|
||||
*/
|
||||
if (sr1 & I2C_SR1_SB) {
|
||||
msg->xferred = 0;
|
||||
i2c_enable_irq(dev, I2C_IRQ_BUFFER);
|
||||
|
||||
/*
|
||||
* Master receiver
|
||||
*/
|
||||
if (read) {
|
||||
i2c_enable_ack(dev);
|
||||
}
|
||||
|
||||
i2c_send_slave_addr(dev, msg->addr, read);
|
||||
sr1 = sr2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* EV6: Slave address sent
|
||||
*/
|
||||
if (sr1 & I2C_SR1_ADDR) {
|
||||
/*
|
||||
* Special case event EV6_1 for master receiver.
|
||||
* Generate NACK and restart/stop condition after ADDR
|
||||
* is cleared.
|
||||
*/
|
||||
if (read) {
|
||||
if (msg->length == 1) {
|
||||
i2c_disable_ack(dev);
|
||||
if (dev->msgs_left > 1) {
|
||||
i2c_start_condition(dev);
|
||||
I2C_CRUMB(RX_ADDR_START, 0, 0);
|
||||
} else {
|
||||
i2c_stop_condition(dev);
|
||||
I2C_CRUMB(RX_ADDR_STOP, 0, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Master transmitter: write first byte to fill shift
|
||||
* register. We should get another TXE interrupt
|
||||
* immediately to fill DR again.
|
||||
*/
|
||||
if (msg->length > 1) {
|
||||
i2c_write(dev, msg->data[msg->xferred++]);
|
||||
} else if (msg->length == 0) { /* We're just sending an address */
|
||||
i2c_stop_condition(dev);
|
||||
/*
|
||||
* Turn off event interrupts to keep BTF from firing until
|
||||
* the end of the stop condition. Why on earth they didn't
|
||||
* have a start/stop condition request clear BTF is beyond
|
||||
* me.
|
||||
*/
|
||||
i2c_disable_irq(dev, I2C_IRQ_EVENT);
|
||||
I2C_CRUMB(STOP_SENT, 0, 0);
|
||||
dev->state = I2C_STATE_XFER_DONE;
|
||||
} /* else we're just sending one byte */
|
||||
}
|
||||
sr1 = sr2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* EV8: Master transmitter
|
||||
* Transmit buffer empty, but we haven't finished transmitting the last
|
||||
* byte written.
|
||||
*/
|
||||
if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) {
|
||||
I2C_CRUMB(TXE_ONLY, 0, 0);
|
||||
if (dev->msgs_left) {
|
||||
i2c_write(dev, msg->data[msg->xferred++]);
|
||||
if (msg->xferred == msg->length) {
|
||||
/*
|
||||
* End of this message. Turn off TXE/RXNE and wait for
|
||||
* BTF to send repeated start or stop condition.
|
||||
*/
|
||||
i2c_disable_irq(dev, I2C_IRQ_BUFFER);
|
||||
dev->msgs_left--;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This should be impossible...
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
sr1 = sr2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* EV8_2: Master transmitter
|
||||
* Last byte sent, program repeated start/stop
|
||||
*/
|
||||
if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) {
|
||||
I2C_CRUMB(TXE_BTF, 0, 0);
|
||||
if (dev->msgs_left) {
|
||||
I2C_CRUMB(TEST, 0, 0);
|
||||
/*
|
||||
* Repeated start insanity: We can't disable ITEVTEN or else SB
|
||||
* won't interrupt, but if we don't disable ITEVTEN, BTF will
|
||||
* continually interrupt us. What the fuck ST?
|
||||
*/
|
||||
i2c_start_condition(dev);
|
||||
while (!(dev->regs->SR1 & I2C_SR1_SB))
|
||||
;
|
||||
dev->msg++;
|
||||
} else {
|
||||
i2c_stop_condition(dev);
|
||||
|
||||
/*
|
||||
* Turn off event interrupts to keep BTF from firing until
|
||||
* the end of the stop condition. Why on earth they didn't
|
||||
* have a start/stop condition request clear BTF is beyond
|
||||
* me.
|
||||
*/
|
||||
i2c_disable_irq(dev, I2C_IRQ_EVENT);
|
||||
I2C_CRUMB(STOP_SENT, 0, 0);
|
||||
dev->state = I2C_STATE_XFER_DONE;
|
||||
}
|
||||
sr1 = sr2 = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* EV7: Master Receiver
|
||||
*/
|
||||
if (sr1 & I2C_SR1_RXNE) {
|
||||
I2C_CRUMB(RXNE_ONLY, 0, 0);
|
||||
msg->data[msg->xferred++] = dev->regs->DR;
|
||||
|
||||
/*
|
||||
* EV7_1: Second to last byte in the reception? Set NACK and generate
|
||||
* stop/restart condition in time for the last byte. We'll get one more
|
||||
* RXNE interrupt before shutting things down.
|
||||
*/
|
||||
if (msg->xferred == (msg->length - 1)) {
|
||||
i2c_disable_ack(dev);
|
||||
if (dev->msgs_left > 2) {
|
||||
i2c_start_condition(dev);
|
||||
I2C_CRUMB(RXNE_START_SENT, 0, 0);
|
||||
} else {
|
||||
i2c_stop_condition(dev);
|
||||
I2C_CRUMB(RXNE_STOP_SENT, 0, 0);
|
||||
}
|
||||
} else if (msg->xferred == msg->length) {
|
||||
dev->msgs_left--;
|
||||
if (dev->msgs_left == 0) {
|
||||
/*
|
||||
* We're done.
|
||||
*/
|
||||
I2C_CRUMB(RXNE_DONE, 0, 0);
|
||||
dev->state = I2C_STATE_XFER_DONE;
|
||||
} else {
|
||||
dev->msg++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler for I2C error conditions. Aborts any pending I2C
|
||||
* transactions.
|
||||
*/
|
||||
void _i2c_irq_error_handler(i2c_dev *dev) {
|
||||
I2C_CRUMB(ERROR_ENTRY, dev->regs->SR1, dev->regs->SR2);
|
||||
|
||||
dev->error_flags = dev->regs->SR1 & (I2C_SR1_BERR |
|
||||
I2C_SR1_ARLO |
|
||||
I2C_SR1_AF |
|
||||
I2C_SR1_OVR);
|
||||
/* Clear flags */
|
||||
dev->regs->SR1 = 0;
|
||||
dev->regs->SR2 = 0;
|
||||
|
||||
i2c_stop_condition(dev);
|
||||
i2c_disable_irq(dev, I2C_IRQ_BUFFER | I2C_IRQ_EVENT | I2C_IRQ_ERROR);
|
||||
dev->state = I2C_STATE_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* CCR/TRISE configuration helper
|
||||
*/
|
||||
static void set_ccr_trise(i2c_dev *dev, uint32 flags) {
|
||||
uint32 ccr = 0;
|
||||
uint32 trise = 0;
|
||||
uint32 clk_mhz = _i2c_bus_clk(dev);
|
||||
uint32 clk_hz = clk_mhz * (1000 * 1000);
|
||||
|
||||
i2c_set_input_clk(dev, clk_mhz);
|
||||
|
||||
if (flags & I2C_FAST_MODE) {
|
||||
ccr |= I2C_CCR_FS;
|
||||
|
||||
if (flags & I2C_DUTY_16_9) {
|
||||
/* Tlow/Thigh = 16/9 */
|
||||
ccr |= I2C_CCR_DUTY_16_9;
|
||||
ccr |= clk_hz / (400000 * 25);
|
||||
} else {
|
||||
/* Tlow/Thigh = 2 */
|
||||
ccr |= clk_hz / (400000 * 3);
|
||||
}
|
||||
|
||||
trise = (300 * clk_mhz / 1000) + 1;
|
||||
} else {
|
||||
/* Tlow/Thigh = 1 */
|
||||
ccr = clk_hz / (100000 * 2);
|
||||
trise = clk_mhz + 1;
|
||||
}
|
||||
|
||||
/* Set minimum required value if CCR < 1*/
|
||||
if ((ccr & I2C_CCR_CCR) == 0) {
|
||||
ccr |= 0x1;
|
||||
}
|
||||
|
||||
i2c_set_clk_control(dev, ccr);
|
||||
i2c_set_trise(dev, trise);
|
||||
}
|
129
BootLoaders/Boards/stm32/cores/maple/libmaple/i2c_f1.c
Normal file
129
BootLoaders/Boards/stm32/cores/maple/libmaple/i2c_f1.c
Normal file
@ -0,0 +1,129 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/i2c.c
|
||||
* @brief STM32F1 I2C support
|
||||
*/
|
||||
|
||||
#include "i2c_private.h"
|
||||
#include <libmaple/i2c.h>
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
static i2c_dev i2c1 = I2C_DEV_OLD(1, &gpiob, 7, 6);
|
||||
static i2c_dev i2c2 = I2C_DEV_OLD(2, &gpiob, 11, 10);
|
||||
|
||||
/** STM32F1 I2C device 1 */
|
||||
i2c_dev* const I2C1 = &i2c1;
|
||||
/** STM32F1 I2C device 2 */
|
||||
i2c_dev* const I2C2 = &i2c2;
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
static int i2c1_wants_remap(const i2c_dev *dev) {
|
||||
/* Check if we've got I2C1 configured for SDA/SCL remap on PB9/PB8 */
|
||||
return (dev->clk_id == RCC_I2C1) &&
|
||||
(scl_port(dev)->clk_id == RCC_GPIOB) &&
|
||||
(sda_port(dev)->clk_id == RCC_GPIOB) &&
|
||||
(dev->sda_pin == 9) &&
|
||||
(dev->scl_pin == 8);
|
||||
}
|
||||
|
||||
void i2c_config_gpios(const i2c_dev *dev) {
|
||||
if (i2c1_wants_remap(dev)) {
|
||||
afio_remap(AFIO_REMAP_I2C1);
|
||||
}
|
||||
gpio_set_mode(sda_port(dev), dev->sda_pin, GPIO_AF_OUTPUT_OD);
|
||||
gpio_set_mode(scl_port(dev), dev->scl_pin, GPIO_AF_OUTPUT_OD);
|
||||
}
|
||||
|
||||
void i2c_master_release_bus(const i2c_dev *dev) {
|
||||
gpio_write_bit(scl_port(dev), dev->scl_pin, 1);
|
||||
gpio_write_bit(sda_port(dev), dev->sda_pin, 1);
|
||||
gpio_set_mode(scl_port(dev), dev->scl_pin, GPIO_OUTPUT_OD);
|
||||
gpio_set_mode(sda_port(dev), dev->sda_pin, GPIO_OUTPUT_OD);
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ handlers
|
||||
*/
|
||||
|
||||
void __irq_i2c1_ev(void) {
|
||||
_i2c_irq_handler(I2C1);
|
||||
}
|
||||
|
||||
void __irq_i2c2_ev(void) {
|
||||
_i2c_irq_handler(I2C2);
|
||||
}
|
||||
|
||||
void __irq_i2c1_er(void) {
|
||||
_i2c_irq_error_handler(I2C1);
|
||||
}
|
||||
|
||||
void __irq_i2c2_er(void) {
|
||||
_i2c_irq_error_handler(I2C2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal APIs
|
||||
*/
|
||||
|
||||
void _i2c_irq_priority_fixup(i2c_dev *dev) {
|
||||
/*
|
||||
* Important STM32 Errata:
|
||||
*
|
||||
* See STM32F10xx8 and STM32F10xxB Errata sheet (Doc ID 14574 Rev 8),
|
||||
* Section 2.11.1, 2.11.2.
|
||||
*
|
||||
* 2.11.1:
|
||||
* When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not
|
||||
* managed before the current byte is being transferred, problems may be
|
||||
* encountered such as receiving an extra byte, reading the same data twice
|
||||
* or missing data.
|
||||
*
|
||||
* 2.11.2:
|
||||
* In Master Receiver mode, when closing the communication using
|
||||
* method 2, the content of the last read data can be corrupted.
|
||||
*
|
||||
* If the user software is not able to read the data N-1 before the STOP
|
||||
* condition is generated on the bus, the content of the shift register
|
||||
* (data N) will be corrupted. (data N is shifted 1-bit to the left).
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* In order to ensure that events are not missed, the i2c interrupt must
|
||||
* not be preempted. We set the i2c interrupt priority to be the highest
|
||||
* interrupt in the system (priority level 0). All other interrupts have
|
||||
* been initialized to priority level 16. See nvic_init().
|
||||
*/
|
||||
nvic_irq_set_priority(dev->ev_nvic_line, 0);
|
||||
nvic_irq_set_priority(dev->er_nvic_line, 0);
|
||||
}
|
62
BootLoaders/Boards/stm32/cores/maple/libmaple/iwdg.c
Normal file
62
BootLoaders/Boards/stm32/cores/maple/libmaple/iwdg.c
Normal file
@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Michael Hope.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/iwdg.c
|
||||
* @brief Independent watchdog (IWDG) support
|
||||
*/
|
||||
|
||||
#include <libmaple/iwdg.h>
|
||||
|
||||
/**
|
||||
* @brief Initialise and start the watchdog
|
||||
*
|
||||
* The prescaler and reload set the timeout. For example, a prescaler
|
||||
* of IWDG_PRE_32 divides the 40 kHz clock by 32 and gives roughly 1
|
||||
* ms per reload.
|
||||
*
|
||||
* @param prescaler Prescaler for the 40 kHz IWDG clock.
|
||||
* @param reload Independent watchdog counter reload value.
|
||||
*/
|
||||
void iwdg_init(iwdg_prescaler prescaler, uint16 reload) {
|
||||
IWDG_BASE->KR = IWDG_KR_UNLOCK;
|
||||
IWDG_BASE->PR = prescaler;
|
||||
IWDG_BASE->RLR = reload;
|
||||
|
||||
/* Start things off */
|
||||
IWDG_BASE->KR = IWDG_KR_START;
|
||||
iwdg_feed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the IWDG counter.
|
||||
*
|
||||
* Calling this function will cause the IWDG counter to be reset to
|
||||
* its reload value.
|
||||
*/
|
||||
void iwdg_feed(void) {
|
||||
IWDG_BASE->KR = IWDG_KR_FEED;
|
||||
}
|
103
BootLoaders/Boards/stm32/cores/maple/libmaple/nvic.c
Normal file
103
BootLoaders/Boards/stm32/cores/maple/libmaple/nvic.c
Normal file
@ -0,0 +1,103 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/nvic.c
|
||||
* @brief Nested vector interrupt controller support.
|
||||
*/
|
||||
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/scb.h>
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
/**
|
||||
* @brief Set interrupt priority for an interrupt line
|
||||
*
|
||||
* Note: The STM32 only implements 4 bits of priority, ignoring the
|
||||
* lower 4 bits. This means there are only 16 levels of priority.
|
||||
* Bits[3:0] read as zero and ignore writes.
|
||||
*
|
||||
* @param irqn device to set
|
||||
* @param priority Priority to set, 0 being highest priority and 15
|
||||
* being lowest.
|
||||
*/
|
||||
void nvic_irq_set_priority(nvic_irq_num irqn, uint8 priority) {
|
||||
if (irqn < 0) {
|
||||
/* This interrupt is in the system handler block */
|
||||
SCB_BASE->SHP[((uint32)irqn & 0xF) - 4] = (priority & 0xF) << 4;
|
||||
} else {
|
||||
NVIC_BASE->IP[irqn] = (priority & 0xF) << 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the NVIC, setting interrupts to a default priority.
|
||||
*/
|
||||
void nvic_init(uint32 address, uint32 offset) {
|
||||
uint32 i;
|
||||
|
||||
nvic_set_vector_table(address, offset);
|
||||
|
||||
/*
|
||||
* Lower priority level for all peripheral interrupts to lowest
|
||||
* possible.
|
||||
*/
|
||||
for (i = 0; i < STM32_NR_INTERRUPTS; i++) {
|
||||
nvic_irq_set_priority((nvic_irq_num)i, 0xF);
|
||||
}
|
||||
|
||||
/* Lower systick interrupt priority to lowest level */
|
||||
nvic_irq_set_priority(NVIC_SYSTICK, 0xF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the vector table base address.
|
||||
*
|
||||
* For stand-alone products, the vector table base address is normally
|
||||
* the start of Flash (0x08000000).
|
||||
*
|
||||
* @param address Vector table base address.
|
||||
* @param offset Offset from address. Some restrictions apply to the
|
||||
* use of nonzero offsets; see the ARM Cortex M3
|
||||
* Technical Reference Manual.
|
||||
*/
|
||||
void nvic_set_vector_table(uint32 address, uint32 offset) {
|
||||
SCB_BASE->VTOR = address | (offset & 0x1FFFFF80);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force a system reset.
|
||||
*
|
||||
* Resets all major system components, excluding debug.
|
||||
*/
|
||||
void nvic_sys_reset() {
|
||||
uint32 prigroup = SCB_BASE->AIRCR & SCB_AIRCR_PRIGROUP;
|
||||
SCB_BASE->AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ | prigroup;
|
||||
asm volatile("dsb");
|
||||
while (1)
|
||||
;
|
||||
}
|
41
BootLoaders/Boards/stm32/cores/maple/libmaple/pwr.c
Normal file
41
BootLoaders/Boards/stm32/cores/maple/libmaple/pwr.c
Normal file
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/pwr.c
|
||||
* @brief Power control (PWR) support.
|
||||
*/
|
||||
|
||||
#include <libmaple/pwr.h>
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
/**
|
||||
* Enables the power interface clock, and resets the power device.
|
||||
*/
|
||||
void pwr_init(void) {
|
||||
rcc_clk_enable(RCC_PWR);
|
||||
rcc_reset_dev(RCC_PWR);
|
||||
}
|
169
BootLoaders/Boards/stm32/cores/maple/libmaple/rcc.c
Normal file
169
BootLoaders/Boards/stm32/cores/maple/libmaple/rcc.c
Normal file
@ -0,0 +1,169 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/rcc.c
|
||||
* @brief Portable RCC routines.
|
||||
*/
|
||||
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
#include "rcc_private.h"
|
||||
|
||||
/**
|
||||
* @brief Get a peripheral's clock domain
|
||||
* @param id Clock ID of the peripheral whose clock domain to return
|
||||
* @return Clock source for the given clock ID
|
||||
*/
|
||||
rcc_clk_domain rcc_dev_clk(rcc_clk_id id) {
|
||||
return rcc_dev_table[id].clk_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Switch the clock used as the source of the system clock.
|
||||
*
|
||||
* After switching the source, this function blocks until the new
|
||||
* clock source is in use.
|
||||
*
|
||||
* @param sysclk_src New system clock source.
|
||||
* @see rcc_sysclk_src
|
||||
*/
|
||||
void rcc_switch_sysclk(rcc_sysclk_src sysclk_src) {
|
||||
uint32 cfgr = RCC_BASE->CFGR;
|
||||
cfgr &= ~RCC_CFGR_SW;
|
||||
cfgr |= sysclk_src;
|
||||
|
||||
/* Switch SYSCLK source. */
|
||||
RCC_BASE->CFGR = cfgr;
|
||||
|
||||
/* Wait for new source to come into use. */
|
||||
while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != (sysclk_src << 2))
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turning clocks off and on, querying their status.
|
||||
*/
|
||||
|
||||
/* IMPORTANT NOTE FOR IMPLEMENTORS:
|
||||
*
|
||||
* libmaple assumes that enum rcc_clk enumerators are two-byte
|
||||
* values, stored in a uint16, in the following way:
|
||||
*
|
||||
* - The high-order byte is the byte offset (from RCC_BASE) of the register
|
||||
* to touch when turning on or off the given clock.
|
||||
*
|
||||
* - The low-order byte is the bit in that register that turns the
|
||||
* clock on or off.
|
||||
*
|
||||
* Example for STM32F1: Turning on the high-speed external clock (HSE)
|
||||
* involves setting HSEON, bit 16, of RCC_CR. The high-order byte is
|
||||
* then offsetof(struct rcc_reg_map, CR) = 0, and the low-order byte
|
||||
* is 16.
|
||||
*
|
||||
* The corresponding value of RCC_CLK_HSE is thus (0 << 8) | 16 = 16.
|
||||
*
|
||||
* On all known STM32 series, this encoding has the property that
|
||||
* adding one to the low byte also gives the bit to check to determine
|
||||
* if the clock is ready. For example, on STM32F1, RCC_CR_HSERDY is
|
||||
* bit 17. If that's not the case on your series, rcc_is_clk_ready()
|
||||
* won't work for you. */
|
||||
|
||||
/* Returns the RCC register which controls the clock source. */
|
||||
static inline __io uint32* rcc_clk_reg(rcc_clk clock) {
|
||||
return (__io uint32*)((__io uint8*)RCC_BASE + (clock >> 8));
|
||||
}
|
||||
|
||||
/* Returns a mask in rcc_clk_reg(clock) to be used for turning the
|
||||
* clock on and off */
|
||||
static inline uint32 rcc_clk_on_mask(rcc_clk clock) {
|
||||
return 1 << (clock & 0xFF);
|
||||
}
|
||||
|
||||
/* Returns a mask in rcc_clk_reg(clock) to be used when checking the
|
||||
* readiness of the clock. */
|
||||
static inline uint32 rcc_clk_ready_mask(rcc_clk clock) {
|
||||
return rcc_clk_on_mask(clock) << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn on a clock source.
|
||||
*
|
||||
* After this routine exits, callers should ensure that the clock
|
||||
* source is ready by waiting until rcc_is_clk_ready(clock) returns
|
||||
* true.
|
||||
*
|
||||
* @param clock Clock to turn on.
|
||||
* @see rcc_turn_off_clk()
|
||||
* @see rcc_is_clk_ready()
|
||||
*/
|
||||
void rcc_turn_on_clk(rcc_clk clock) {
|
||||
*rcc_clk_reg(clock) |= rcc_clk_on_mask(clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn off a clock source.
|
||||
*
|
||||
* In certain configurations, certain clock sources cannot be safely
|
||||
* turned off. (For example, the main PLL on STM32F1 devices cannot be
|
||||
* turned off if it has been selected as the SYSCLK source). Consult
|
||||
* the reference material for your MCU to ensure it is safe to call
|
||||
* this function.
|
||||
*
|
||||
* @param clock Clock to turn off.
|
||||
* @see rcc_turn_on_clk()
|
||||
* @see rcc_is_clk_ready()
|
||||
*/
|
||||
void rcc_turn_off_clk(rcc_clk clock) {
|
||||
*rcc_clk_reg(clock) &= ~rcc_clk_on_mask(clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if a clock is on.
|
||||
* @param clock Clock to check.
|
||||
* @return 1 if the clock is on, 0 if the clock is off.
|
||||
*/
|
||||
int rcc_is_clk_on(rcc_clk clock) {
|
||||
return !!(*rcc_clk_reg(clock) & rcc_clk_on_mask(clock));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if a clock source is ready.
|
||||
*
|
||||
* In general, it is not safe to rely on a clock source unless this
|
||||
* function returns nonzero. Also note that this function may return
|
||||
* nonzero for a short period of time after a clock has been turned
|
||||
* off. Consult the reference material for your MCU for more details.
|
||||
*
|
||||
* @param clock Clock whose readiness to check for.
|
||||
* @return Nonzero if the clock is ready, zero otherwise.
|
||||
* @see rcc_turn_on_clk()
|
||||
* @see rcc_turn_off_clk()
|
||||
*/
|
||||
int rcc_is_clk_ready(rcc_clk clock) {
|
||||
return (int)(*rcc_clk_reg(clock) & rcc_clk_ready_mask(clock));
|
||||
}
|
173
BootLoaders/Boards/stm32/cores/maple/libmaple/rcc_f1.c
Normal file
173
BootLoaders/Boards/stm32/cores/maple/libmaple/rcc_f1.c
Normal file
@ -0,0 +1,173 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/rcc.c
|
||||
* @brief STM32F1 RCC.
|
||||
*/
|
||||
|
||||
#include <libmaple/rcc.h>
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/bitband.h>
|
||||
|
||||
#include "rcc_private.h"
|
||||
|
||||
#define APB1 RCC_APB1
|
||||
#define APB2 RCC_APB2
|
||||
#define AHB RCC_AHB
|
||||
|
||||
/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
|
||||
* register bit numbers. */
|
||||
const struct rcc_dev_info rcc_dev_table[] = {
|
||||
[RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 },
|
||||
[RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 },
|
||||
[RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 },
|
||||
[RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 },
|
||||
[RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 },
|
||||
[RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 },
|
||||
[RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 },
|
||||
[RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 },
|
||||
[RCC_USART1] = { .clk_domain = APB2, .line_num = 14 },
|
||||
[RCC_USART2] = { .clk_domain = APB1, .line_num = 17 },
|
||||
[RCC_USART3] = { .clk_domain = APB1, .line_num = 18 },
|
||||
[RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 },
|
||||
[RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 },
|
||||
[RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 },
|
||||
[RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 },
|
||||
[RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 },
|
||||
[RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 },
|
||||
[RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 },
|
||||
[RCC_PWR] = { .clk_domain = APB1, .line_num = 28},
|
||||
[RCC_BKP] = { .clk_domain = APB1, .line_num = 27},
|
||||
[RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 },
|
||||
[RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 },
|
||||
[RCC_CRC] = { .clk_domain = AHB, .line_num = 6},
|
||||
[RCC_FLITF] = { .clk_domain = AHB, .line_num = 4},
|
||||
[RCC_SRAM] = { .clk_domain = AHB, .line_num = 2},
|
||||
[RCC_USB] = { .clk_domain = APB1, .line_num = 23},
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
[RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 },
|
||||
[RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 },
|
||||
[RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 },
|
||||
[RCC_UART4] = { .clk_domain = APB1, .line_num = 19 },
|
||||
[RCC_UART5] = { .clk_domain = APB1, .line_num = 20 },
|
||||
[RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 },
|
||||
[RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 },
|
||||
[RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 },
|
||||
[RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 },
|
||||
[RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 },
|
||||
[RCC_DAC] = { .clk_domain = APB1, .line_num = 29 },
|
||||
[RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 },
|
||||
[RCC_SDIO] = { .clk_domain = AHB, .line_num = 10 },
|
||||
[RCC_SPI3] = { .clk_domain = APB1, .line_num = 15 },
|
||||
#endif
|
||||
#ifdef STM32_XL_DENSITY
|
||||
[RCC_TIMER9] = { .clk_domain = APB2, .line_num = 19 },
|
||||
[RCC_TIMER10] = { .clk_domain = APB2, .line_num = 20 },
|
||||
[RCC_TIMER11] = { .clk_domain = APB2, .line_num = 21 },
|
||||
[RCC_TIMER12] = { .clk_domain = APB1, .line_num = 6 },
|
||||
[RCC_TIMER13] = { .clk_domain = APB1, .line_num = 7 },
|
||||
[RCC_TIMER14] = { .clk_domain = APB1, .line_num = 8 },
|
||||
#endif
|
||||
};
|
||||
|
||||
__deprecated
|
||||
void rcc_clk_init(rcc_sysclk_src sysclk_src,
|
||||
rcc_pllsrc pll_src,
|
||||
rcc_pll_multiplier pll_mul) {
|
||||
/* Assume that we're going to clock the chip off the PLL, fed by
|
||||
* the HSE */
|
||||
ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
|
||||
pll_src == RCC_PLLSRC_HSE);
|
||||
|
||||
RCC_BASE->CFGR = pll_src | pll_mul | (0x3<<22);
|
||||
|
||||
/* Turn on, and wait for, HSE. */
|
||||
rcc_turn_on_clk(RCC_CLK_HSE);
|
||||
while (!rcc_is_clk_ready(RCC_CLK_HSE))
|
||||
;
|
||||
|
||||
/* Do the same for the main PLL. */
|
||||
rcc_turn_on_clk(RCC_CLK_PLL);
|
||||
while(!rcc_is_clk_ready(RCC_CLK_PLL))
|
||||
;
|
||||
|
||||
/* Finally, switch over to the PLL. */
|
||||
rcc_switch_sysclk(RCC_CLKSRC_PLL);
|
||||
}
|
||||
|
||||
/* pll_cfg->data must point to a valid struct stm32f1_rcc_pll_data. */
|
||||
void rcc_configure_pll(rcc_pll_cfg *pll_cfg) {
|
||||
stm32f1_rcc_pll_data *data = pll_cfg->data;
|
||||
rcc_pll_multiplier pll_mul = data->pll_mul;
|
||||
uint32 cfgr;
|
||||
/* Check that the PLL is disabled. */
|
||||
ASSERT_FAULT(!rcc_is_clk_on(RCC_CLK_PLL));
|
||||
|
||||
cfgr = RCC_BASE->CFGR;
|
||||
cfgr &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL);
|
||||
cfgr |= pll_cfg->pllsrc | pll_mul;
|
||||
|
||||
RCC_BASE->CFGR = cfgr;
|
||||
}
|
||||
|
||||
void rcc_clk_enable(rcc_clk_id id) {
|
||||
static __io uint32* enable_regs[] = {
|
||||
[APB1] = &RCC_BASE->APB1ENR,
|
||||
[APB2] = &RCC_BASE->APB2ENR,
|
||||
[AHB] = &RCC_BASE->AHBENR,
|
||||
};
|
||||
rcc_do_clk_enable(enable_regs, id);
|
||||
}
|
||||
|
||||
void rcc_reset_dev(rcc_clk_id id) {
|
||||
static __io uint32* reset_regs[] = {
|
||||
[APB1] = &RCC_BASE->APB1RSTR,
|
||||
[APB2] = &RCC_BASE->APB2RSTR,
|
||||
};
|
||||
rcc_do_reset_dev(reset_regs, id);
|
||||
}
|
||||
|
||||
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider) {
|
||||
static const uint32 masks[] = {
|
||||
[RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
|
||||
[RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
|
||||
[RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
|
||||
[RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
|
||||
[RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
|
||||
};
|
||||
rcc_do_set_prescaler(masks, prescaler, divider);
|
||||
}
|
||||
|
||||
void rcc_clk_disable(rcc_clk_id id) {
|
||||
static __io uint32* enable_regs[] = {
|
||||
[APB1] = &RCC_BASE->APB1ENR,
|
||||
[APB2] = &RCC_BASE->APB2ENR,
|
||||
[AHB] = &RCC_BASE->AHBENR,
|
||||
};
|
||||
rcc_do_clk_disable(enable_regs, id);
|
||||
}
|
172
BootLoaders/Boards/stm32/cores/maple/libmaple/spi.c
Normal file
172
BootLoaders/Boards/stm32/cores/maple/libmaple/spi.c
Normal file
@ -0,0 +1,172 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/spi.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief Serial Peripheral Interface (SPI) support.
|
||||
* Currently, there is no Integrated Interchip Sound (I2S) support.
|
||||
*/
|
||||
|
||||
#include <libmaple/spi.h>
|
||||
#include <libmaple/bitband.h>
|
||||
|
||||
static void spi_reconfigure(spi_dev *dev, uint32 cr1_config);
|
||||
|
||||
/*
|
||||
* SPI convenience routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize and reset a SPI device.
|
||||
* @param dev Device to initialize and reset.
|
||||
*/
|
||||
void spi_init(spi_dev *dev) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
rcc_reset_dev(dev->clk_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure and enable a SPI device as bus master.
|
||||
*
|
||||
* The device's peripheral will be disabled before being reconfigured.
|
||||
*
|
||||
* @param dev Device to configure as bus master
|
||||
* @param baud Bus baud rate
|
||||
* @param mode SPI mode
|
||||
* @param flags Logical OR of spi_cfg_flag values.
|
||||
* @see spi_cfg_flag
|
||||
*/
|
||||
void spi_master_enable(spi_dev *dev,
|
||||
spi_baud_rate baud,
|
||||
spi_mode mode,
|
||||
uint32 flags) {
|
||||
spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure and enable a SPI device as a bus slave.
|
||||
*
|
||||
* The device's peripheral will be disabled before being reconfigured.
|
||||
*
|
||||
* @param dev Device to configure as a bus slave
|
||||
* @param mode SPI mode
|
||||
* @param flags Logical OR of spi_cfg_flag values.
|
||||
* @see spi_cfg_flag
|
||||
*/
|
||||
void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) {
|
||||
spi_reconfigure(dev, flags | mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Blocking SPI transmit.
|
||||
* @param dev SPI port to use for transmission
|
||||
* @param buf Buffer to transmit. The sizeof buf's elements are
|
||||
* inferred from dev's data frame format (i.e., are
|
||||
* correctly treated as 8-bit or 16-bit quantities).
|
||||
* @param len Maximum number of elements to transmit.
|
||||
* @return Number of elements transmitted.
|
||||
*/
|
||||
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
|
||||
uint32 txed = len;
|
||||
spi_reg_map *regs = dev->regs;
|
||||
if ( spi_dff(dev) == SPI_DFF_8_BIT ) {
|
||||
const uint8 * dp8 = (const uint8*)buf;
|
||||
while ( len-- ) {
|
||||
while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
|
||||
regs->DR = *dp8++;
|
||||
}
|
||||
} else {
|
||||
const uint16 * dp16 = (const uint16*)buf;
|
||||
while ( len-- ) {
|
||||
while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
|
||||
regs->DR = *dp16++;
|
||||
}
|
||||
}
|
||||
return txed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a SPI peripheral
|
||||
* @param dev Device to enable
|
||||
*/
|
||||
void spi_peripheral_enable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a SPI peripheral
|
||||
* @param dev Device to disable
|
||||
*/
|
||||
void spi_peripheral_disable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR1, SPI_CR1_SPE_BIT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA requests whenever the transmit buffer is empty
|
||||
* @param dev SPI device on which to enable TX DMA requests
|
||||
*/
|
||||
void spi_tx_dma_enable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable DMA requests whenever the transmit buffer is empty
|
||||
* @param dev SPI device on which to disable TX DMA requests
|
||||
*/
|
||||
void spi_tx_dma_disable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_TXDMAEN_BIT, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA requests whenever the receive buffer is empty
|
||||
* @param dev SPI device on which to enable RX DMA requests
|
||||
*/
|
||||
void spi_rx_dma_enable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable DMA requests whenever the receive buffer is empty
|
||||
* @param dev SPI device on which to disable RX DMA requests
|
||||
*/
|
||||
void spi_rx_dma_disable(spi_dev *dev) {
|
||||
bb_peri_set_bit(&dev->regs->CR2, SPI_CR2_RXDMAEN_BIT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPI auxiliary routines
|
||||
*/
|
||||
|
||||
static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
|
||||
#define MASK (SPI_CR1_CRCEN|SPI_CR1_DFF)
|
||||
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
|
||||
if ( (dev->regs->CR1&MASK)!=(cr1_config&MASK) ) spi_peripheral_disable(dev);
|
||||
dev->regs->CR1 = cr1_config;
|
||||
spi_peripheral_enable(dev);
|
||||
}
|
84
BootLoaders/Boards/stm32/cores/maple/libmaple/spi_f1.c
Normal file
84
BootLoaders/Boards/stm32/cores/maple/libmaple/spi_f1.c
Normal file
@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/spi.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief STM32F1 SPI/I2S.
|
||||
*/
|
||||
|
||||
#include <libmaple/spi.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include "spi_private.h"
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
static spi_dev spi1 = SPI_DEV(1);
|
||||
static spi_dev spi2 = SPI_DEV(2);
|
||||
|
||||
spi_dev *SPI1 = &spi1;
|
||||
spi_dev *SPI2 = &spi2;
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
static spi_dev spi3 = SPI_DEV(3);
|
||||
spi_dev *SPI3 = &spi3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
void spi_config_gpios(spi_dev *ignored,
|
||||
uint8 as_master,
|
||||
gpio_dev *nss_dev,
|
||||
uint8 nss_bit,
|
||||
gpio_dev *comm_dev,
|
||||
uint8 sck_bit,
|
||||
uint8 miso_bit,
|
||||
uint8 mosi_bit) {
|
||||
if (as_master) {
|
||||
// gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP);// Roger Clark. Commented out, so that NSS can be driven as a normal GPIO pin during SPI use
|
||||
gpio_set_mode(comm_dev, sck_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(comm_dev, mosi_bit, GPIO_AF_OUTPUT_PP);
|
||||
} else {
|
||||
gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(comm_dev, sck_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(comm_dev, miso_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(comm_dev, mosi_bit, GPIO_INPUT_FLOATING);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_foreach(void (*fn)(spi_dev*)) {
|
||||
fn(SPI1);
|
||||
fn(SPI2);
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
fn(SPI3);
|
||||
#endif
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/* STM32F1 performance line ISR weak declarations */
|
||||
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
.thumb
|
||||
|
||||
/* Default handler for all non-overridden interrupts and exceptions */
|
||||
.globl __default_handler
|
||||
.type __default_handler, %function
|
||||
|
||||
__default_handler:
|
||||
b .
|
||||
|
||||
.weak __exc_nmi
|
||||
.globl __exc_nmi
|
||||
.set __exc_nmi, __default_handler
|
||||
.weak __exc_hardfault
|
||||
.globl __exc_hardfault
|
||||
.set __exc_hardfault, __default_handler
|
||||
.weak __exc_memmanage
|
||||
.globl __exc_memmanage
|
||||
.set __exc_memmanage, __default_handler
|
||||
.weak __exc_busfault
|
||||
.globl __exc_busfault
|
||||
.set __exc_busfault, __default_handler
|
||||
.weak __exc_usagefault
|
||||
.globl __exc_usagefault
|
||||
.set __exc_usagefault, __default_handler
|
||||
.weak __stm32reservedexception7
|
||||
.globl __stm32reservedexception7
|
||||
.set __stm32reservedexception7, __default_handler
|
||||
.weak __stm32reservedexception8
|
||||
.globl __stm32reservedexception8
|
||||
.set __stm32reservedexception8, __default_handler
|
||||
.weak __stm32reservedexception9
|
||||
.globl __stm32reservedexception9
|
||||
.set __stm32reservedexception9, __default_handler
|
||||
.weak __stm32reservedexception10
|
||||
.globl __stm32reservedexception10
|
||||
.set __stm32reservedexception10, __default_handler
|
||||
.weak __exc_svc
|
||||
.globl __exc_svc
|
||||
.set __exc_svc, __default_handler
|
||||
.weak __exc_debug_monitor
|
||||
.globl __exc_debug_monitor
|
||||
.set __exc_debug_monitor, __default_handler
|
||||
.weak __stm32reservedexception13
|
||||
.globl __stm32reservedexception13
|
||||
.set __stm32reservedexception13, __default_handler
|
||||
.weak __exc_pendsv
|
||||
.globl __exc_pendsv
|
||||
.set __exc_pendsv, __default_handler
|
||||
.weak __exc_systick
|
||||
.globl __exc_systick
|
||||
.set __exc_systick, __default_handler
|
||||
.weak __irq_wwdg
|
||||
.globl __irq_wwdg
|
||||
.set __irq_wwdg, __default_handler
|
||||
.weak __irq_pvd
|
||||
.globl __irq_pvd
|
||||
.set __irq_pvd, __default_handler
|
||||
.weak __irq_tamper
|
||||
.globl __irq_tamper
|
||||
.set __irq_tamper, __default_handler
|
||||
.weak __irq_rtc
|
||||
.globl __irq_rtc
|
||||
.set __irq_rtc, __default_handler
|
||||
.weak __irq_flash
|
||||
.globl __irq_flash
|
||||
.set __irq_flash, __default_handler
|
||||
.weak __irq_rcc
|
||||
.globl __irq_rcc
|
||||
.set __irq_rcc, __default_handler
|
||||
.weak __irq_exti0
|
||||
.globl __irq_exti0
|
||||
.set __irq_exti0, __default_handler
|
||||
.weak __irq_exti1
|
||||
.globl __irq_exti1
|
||||
.set __irq_exti1, __default_handler
|
||||
.weak __irq_exti2
|
||||
.globl __irq_exti2
|
||||
.set __irq_exti2, __default_handler
|
||||
.weak __irq_exti3
|
||||
.globl __irq_exti3
|
||||
.set __irq_exti3, __default_handler
|
||||
.weak __irq_exti4
|
||||
.globl __irq_exti4
|
||||
.set __irq_exti4, __default_handler
|
||||
.weak __irq_dma1_channel1
|
||||
.globl __irq_dma1_channel1
|
||||
.set __irq_dma1_channel1, __default_handler
|
||||
.weak __irq_dma1_channel2
|
||||
.globl __irq_dma1_channel2
|
||||
.set __irq_dma1_channel2, __default_handler
|
||||
.weak __irq_dma1_channel3
|
||||
.globl __irq_dma1_channel3
|
||||
.set __irq_dma1_channel3, __default_handler
|
||||
.weak __irq_dma1_channel4
|
||||
.globl __irq_dma1_channel4
|
||||
.set __irq_dma1_channel4, __default_handler
|
||||
.weak __irq_dma1_channel5
|
||||
.globl __irq_dma1_channel5
|
||||
.set __irq_dma1_channel5, __default_handler
|
||||
.weak __irq_dma1_channel6
|
||||
.globl __irq_dma1_channel6
|
||||
.set __irq_dma1_channel6, __default_handler
|
||||
.weak __irq_dma1_channel7
|
||||
.globl __irq_dma1_channel7
|
||||
.set __irq_dma1_channel7, __default_handler
|
||||
.weak __irq_adc
|
||||
.globl __irq_adc
|
||||
.set __irq_adc, __default_handler
|
||||
.weak __irq_usb_hp_can_tx
|
||||
.globl __irq_usb_hp_can_tx
|
||||
.set __irq_usb_hp_can_tx, __default_handler
|
||||
.weak __irq_usb_lp_can_rx0
|
||||
.globl __irq_usb_lp_can_rx0
|
||||
.set __irq_usb_lp_can_rx0, __default_handler
|
||||
.weak __irq_can_rx1
|
||||
.globl __irq_can_rx1
|
||||
.set __irq_can_rx1, __default_handler
|
||||
.weak __irq_can_sce
|
||||
.globl __irq_can_sce
|
||||
.set __irq_can_sce, __default_handler
|
||||
.weak __irq_exti9_5
|
||||
.globl __irq_exti9_5
|
||||
.set __irq_exti9_5, __default_handler
|
||||
.weak __irq_tim1_brk
|
||||
.globl __irq_tim1_brk
|
||||
.set __irq_tim1_brk, __default_handler
|
||||
.weak __irq_tim1_up
|
||||
.globl __irq_tim1_up
|
||||
.set __irq_tim1_up, __default_handler
|
||||
.weak __irq_tim1_trg_com
|
||||
.globl __irq_tim1_trg_com
|
||||
.set __irq_tim1_trg_com, __default_handler
|
||||
.weak __irq_tim1_cc
|
||||
.globl __irq_tim1_cc
|
||||
.set __irq_tim1_cc, __default_handler
|
||||
|
||||
.weakref __irq_tim2, __default_handler
|
||||
.globl __irq_tim2
|
||||
.weakref __irq_tim3, __default_handler
|
||||
.globl __irq_tim3
|
||||
.weakref __irq_tim4, __default_handler
|
||||
.globl __irq_tim4
|
||||
|
||||
.weak __irq_i2c1_ev
|
||||
.globl __irq_i2c1_ev
|
||||
.set __irq_i2c1_ev, __default_handler
|
||||
.weak __irq_i2c1_er
|
||||
.globl __irq_i2c1_er
|
||||
.set __irq_i2c1_er, __default_handler
|
||||
.weak __irq_i2c2_ev
|
||||
.globl __irq_i2c2_ev
|
||||
.set __irq_i2c2_ev, __default_handler
|
||||
.weak __irq_i2c2_er
|
||||
.globl __irq_i2c2_er
|
||||
.set __irq_i2c2_er, __default_handler
|
||||
.weak __irq_spi1
|
||||
.globl __irq_spi1
|
||||
.set __irq_spi1, __default_handler
|
||||
.weak __irq_spi2
|
||||
.globl __irq_spi2
|
||||
.set __irq_spi2, __default_handler
|
||||
.weak __irq_usart1
|
||||
.globl __irq_usart1
|
||||
.set __irq_usart1, __default_handler
|
||||
.weak __irq_usart2
|
||||
.globl __irq_usart2
|
||||
.set __irq_usart2, __default_handler
|
||||
.weak __irq_usart3
|
||||
.globl __irq_usart3
|
||||
.set __irq_usart3, __default_handler
|
||||
.weak __irq_exti15_10
|
||||
.globl __irq_exti15_10
|
||||
.set __irq_exti15_10, __default_handler
|
||||
.weak __irq_rtcalarm
|
||||
.globl __irq_rtcalarm
|
||||
.set __irq_rtcalarm, __default_handler
|
||||
.weak __irq_usbwakeup
|
||||
.globl __irq_usbwakeup
|
||||
.set __irq_usbwakeup, __default_handler
|
||||
#if defined (STM32_HIGH_DENSITY)
|
||||
.weak __irq_tim8_brk
|
||||
.globl __irq_tim8_brk
|
||||
.set __irq_tim8_brk, __default_handler
|
||||
.weak __irq_tim8_up
|
||||
.globl __irq_tim8_up
|
||||
.set __irq_tim8_up, __default_handler
|
||||
.weak __irq_tim8_trg_com
|
||||
.globl __irq_tim8_trg_com
|
||||
.set __irq_tim8_trg_com, __default_handler
|
||||
.weak __irq_tim8_cc
|
||||
.globl __irq_tim8_cc
|
||||
.set __irq_tim8_cc, __default_handler
|
||||
.weak __irq_adc3
|
||||
.globl __irq_adc3
|
||||
.set __irq_adc3, __default_handler
|
||||
.weak __irq_fsmc
|
||||
.globl __irq_fsmc
|
||||
.set __irq_fsmc, __default_handler
|
||||
.weak __irq_sdio
|
||||
.globl __irq_sdio
|
||||
.set __irq_sdio, __default_handler
|
||||
.weak __irq_tim5
|
||||
.globl __irq_tim5
|
||||
.set __irq_tim5, __default_handler
|
||||
.weak __irq_spi3
|
||||
.globl __irq_spi3
|
||||
.set __irq_spi3, __default_handler
|
||||
.weak __irq_uart4
|
||||
.globl __irq_uart4
|
||||
.set __irq_uart4, __default_handler
|
||||
.weak __irq_uart5
|
||||
.globl __irq_uart5
|
||||
.set __irq_uart5, __default_handler
|
||||
.weak __irq_tim6
|
||||
.globl __irq_tim6
|
||||
.set __irq_tim6, __default_handler
|
||||
.weak __irq_tim7
|
||||
.globl __irq_tim7
|
||||
.set __irq_tim7, __default_handler
|
||||
.weak __irq_dma2_channel1
|
||||
.globl __irq_dma2_channel1
|
||||
.set __irq_dma2_channel1, __default_handler
|
||||
.weak __irq_dma2_channel2
|
||||
.globl __irq_dma2_channel2
|
||||
.set __irq_dma2_channel2, __default_handler
|
||||
.weak __irq_dma2_channel3
|
||||
.globl __irq_dma2_channel3
|
||||
.set __irq_dma2_channel3, __default_handler
|
||||
.weak __irq_dma2_channel4_5
|
||||
.globl __irq_dma2_channel4_5
|
||||
.set __irq_dma2_channel4_5, __default_handler
|
||||
#endif /* STM32_HIGH_DENSITY */
|
@ -0,0 +1,118 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/* STM32F1 performance line vector table */
|
||||
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
.section ".stm32.interrupt_vector"
|
||||
|
||||
.globl __stm32_vector_table
|
||||
.type __stm32_vector_table, %object
|
||||
|
||||
__stm32_vector_table:
|
||||
/* CM3 core interrupts */
|
||||
.long __msp_init
|
||||
.long __exc_reset
|
||||
.long __exc_nmi
|
||||
.long __exc_hardfault
|
||||
.long __exc_memmanage
|
||||
.long __exc_busfault
|
||||
.long __exc_usagefault
|
||||
.long __stm32reservedexception7
|
||||
.long __stm32reservedexception8
|
||||
.long __stm32reservedexception9
|
||||
.long __stm32reservedexception10
|
||||
.long __exc_svc
|
||||
.long __exc_debug_monitor
|
||||
.long __stm32reservedexception13
|
||||
.long __exc_pendsv
|
||||
.long __exc_systick
|
||||
/* Peripheral interrupts */
|
||||
.long __irq_wwdg
|
||||
.long __irq_pvd
|
||||
.long __irq_tamper
|
||||
.long __irq_rtc
|
||||
.long __irq_flash
|
||||
.long __irq_rcc
|
||||
.long __irq_exti0
|
||||
.long __irq_exti1
|
||||
.long __irq_exti2
|
||||
.long __irq_exti3
|
||||
.long __irq_exti4
|
||||
.long __irq_dma1_channel1
|
||||
.long __irq_dma1_channel2
|
||||
.long __irq_dma1_channel3
|
||||
.long __irq_dma1_channel4
|
||||
.long __irq_dma1_channel5
|
||||
.long __irq_dma1_channel6
|
||||
.long __irq_dma1_channel7
|
||||
.long __irq_adc
|
||||
.long __irq_usb_hp_can_tx
|
||||
.long __irq_usb_lp_can_rx0
|
||||
.long __irq_can_rx1
|
||||
.long __irq_can_sce
|
||||
.long __irq_exti9_5
|
||||
.long __irq_tim1_brk
|
||||
.long __irq_tim1_up
|
||||
.long __irq_tim1_trg_com
|
||||
.long __irq_tim1_cc
|
||||
.long __irq_tim2
|
||||
.long __irq_tim3
|
||||
.long __irq_tim4
|
||||
.long __irq_i2c1_ev
|
||||
.long __irq_i2c1_er
|
||||
.long __irq_i2c2_ev
|
||||
.long __irq_i2c2_er
|
||||
.long __irq_spi1
|
||||
.long __irq_spi2
|
||||
.long __irq_usart1
|
||||
.long __irq_usart2
|
||||
.long __irq_usart3
|
||||
.long __irq_exti15_10
|
||||
.long __irq_rtcalarm
|
||||
.long __irq_usbwakeup
|
||||
#if defined (STM32_HIGH_DENSITY)
|
||||
.long __irq_tim8_brk
|
||||
.long __irq_tim8_up
|
||||
.long __irq_tim8_trg_com
|
||||
.long __irq_tim8_cc
|
||||
.long __irq_adc3
|
||||
.long __irq_fsmc
|
||||
.long __irq_sdio
|
||||
.long __irq_tim5
|
||||
.long __irq_spi3
|
||||
.long __irq_uart4
|
||||
.long __irq_uart5
|
||||
.long __irq_tim6
|
||||
.long __irq_tim7
|
||||
.long __irq_dma2_channel1
|
||||
.long __irq_dma2_channel2
|
||||
.long __irq_dma2_channel3
|
||||
.long __irq_dma2_channel4_5
|
||||
#endif /* STM32_HIGH_DENSITY */
|
||||
|
||||
.size __stm32_vector_table, . - __stm32_vector_table
|
88
BootLoaders/Boards/stm32/cores/maple/libmaple/systick.c
Normal file
88
BootLoaders/Boards/stm32/cores/maple/libmaple/systick.c
Normal file
@ -0,0 +1,88 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2010, 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/systick.c
|
||||
* @brief System timer (SysTick).
|
||||
*/
|
||||
|
||||
#include <libmaple/systick.h>
|
||||
|
||||
volatile uint32 systick_uptime_millis;
|
||||
static void (*systick_user_callback)(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize and enable SysTick.
|
||||
*
|
||||
* Clocks the system timer with the core clock, turns it on, and
|
||||
* enables interrupts.
|
||||
*
|
||||
* @param reload_val Appropriate reload counter to tick every 1 ms.
|
||||
*/
|
||||
void systick_init(uint32 reload_val) {
|
||||
SYSTICK_BASE->RVR = reload_val;
|
||||
systick_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clock the system timer with the core clock, but don't turn it
|
||||
* on or enable interrupt.
|
||||
*/
|
||||
void systick_disable() {
|
||||
SYSTICK_BASE->CSR = SYSTICK_CSR_CLKSOURCE_CORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clock the system timer with the core clock and turn it on;
|
||||
* interrupt every 1 ms, for systick_timer_millis.
|
||||
*/
|
||||
void systick_enable() {
|
||||
/* re-enables init registers without changing reload val */
|
||||
SYSTICK_BASE->CSR = (SYSTICK_CSR_CLKSOURCE_CORE |
|
||||
SYSTICK_CSR_ENABLE |
|
||||
SYSTICK_CSR_TICKINT_PEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Attach a callback to be called from the SysTick exception handler.
|
||||
*
|
||||
* To detach a callback, call this function again with a null argument.
|
||||
*/
|
||||
void systick_attach_callback(void (*callback)(void)) {
|
||||
systick_user_callback = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* SysTick ISR
|
||||
*/
|
||||
|
||||
void __exc_systick(void) {
|
||||
systick_uptime_millis++;
|
||||
if (systick_user_callback) {
|
||||
systick_user_callback();
|
||||
}
|
||||
}
|
550
BootLoaders/Boards/stm32/cores/maple/libmaple/timer.c
Normal file
550
BootLoaders/Boards/stm32/cores/maple/libmaple/timer.c
Normal file
@ -0,0 +1,550 @@
|
||||
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/timer.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief Portable timer routines.
|
||||
*/
|
||||
|
||||
#include <libmaple/timer.h>
|
||||
#include <libmaple/stm32.h>
|
||||
#include "timer_private.h"
|
||||
|
||||
static void disable_channel(timer_dev *dev, uint8 channel);
|
||||
static void pwm_mode(timer_dev *dev, uint8 channel);
|
||||
static void output_compare_mode(timer_dev *dev, uint8 channel);
|
||||
static void encoder_mode(timer_dev *dev, uint8 channel) ;//CARLOS
|
||||
|
||||
|
||||
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid);
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*
|
||||
* Defer to the timer_private API for declaring these.
|
||||
*/
|
||||
|
||||
#if STM32_HAVE_TIMER(1)
|
||||
timer_dev timer1 = ADVANCED_TIMER(1);
|
||||
/** Timer 1 device (advanced) */
|
||||
timer_dev *const TIMER1 = &timer1;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(2)
|
||||
timer_dev timer2 = GENERAL_TIMER(2);
|
||||
/** Timer 2 device (general-purpose) */
|
||||
timer_dev *const TIMER2 = &timer2;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(3)
|
||||
timer_dev timer3 = GENERAL_TIMER(3);
|
||||
/** Timer 3 device (general-purpose) */
|
||||
timer_dev *const TIMER3 = &timer3;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(4)
|
||||
timer_dev timer4 = GENERAL_TIMER(4);
|
||||
/** Timer 4 device (general-purpose) */
|
||||
timer_dev *const TIMER4 = &timer4;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(5)
|
||||
timer_dev timer5 = GENERAL_TIMER(5);
|
||||
/** Timer 5 device (general-purpose) */
|
||||
timer_dev *const TIMER5 = &timer5;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(6)
|
||||
timer_dev timer6 = BASIC_TIMER(6);
|
||||
/** Timer 6 device (basic) */
|
||||
timer_dev *const TIMER6 = &timer6;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(7)
|
||||
timer_dev timer7 = BASIC_TIMER(7);
|
||||
/** Timer 7 device (basic) */
|
||||
timer_dev *const TIMER7 = &timer7;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(8)
|
||||
timer_dev timer8 = ADVANCED_TIMER(8);
|
||||
/** Timer 8 device (advanced) */
|
||||
timer_dev *const TIMER8 = &timer8;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(9)
|
||||
timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT);
|
||||
/** Timer 9 device (general-purpose) */
|
||||
timer_dev *const TIMER9 = &timer9;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(10)
|
||||
timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT);
|
||||
/** Timer 10 device (general-purpose) */
|
||||
timer_dev *const TIMER10 = &timer10;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(11)
|
||||
timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT);
|
||||
/** Timer 11 device (general-purpose) */
|
||||
timer_dev *const TIMER11 = &timer11;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(12)
|
||||
timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT);
|
||||
/** Timer 12 device (general-purpose) */
|
||||
timer_dev *const TIMER12 = &timer12;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(13)
|
||||
timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT);
|
||||
/** Timer 13 device (general-purpose) */
|
||||
timer_dev *const TIMER13 = &timer13;
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(14)
|
||||
timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT);
|
||||
/** Timer 14 device (general-purpose) */
|
||||
timer_dev *const TIMER14 = &timer14;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Call a function on timer devices.
|
||||
* @param fn Function to call on each timer device.
|
||||
*/
|
||||
void timer_foreach(void (*fn)(timer_dev*)) {
|
||||
#if STM32_HAVE_TIMER(1)
|
||||
fn(TIMER1);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(2)
|
||||
fn(TIMER2);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(3)
|
||||
fn(TIMER3);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(4)
|
||||
fn(TIMER4);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(5)
|
||||
fn(TIMER5);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(6)
|
||||
fn(TIMER6);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(7)
|
||||
fn(TIMER7);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(8)
|
||||
fn(TIMER8);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(9)
|
||||
fn(TIMER9);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(10)
|
||||
fn(TIMER10);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(11)
|
||||
fn(TIMER11);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(12)
|
||||
fn(TIMER12);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(13)
|
||||
fn(TIMER13);
|
||||
#endif
|
||||
#if STM32_HAVE_TIMER(14)
|
||||
fn(TIMER14);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a timer, and reset its register map.
|
||||
* @param dev Timer to initialize
|
||||
*/
|
||||
void timer_init(timer_dev *dev) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
rcc_reset_dev(dev->clk_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a timer.
|
||||
*
|
||||
* The timer will stop counting, all DMA requests and interrupts will
|
||||
* be disabled, and no state changes will be output.
|
||||
*
|
||||
* @param dev Timer to disable.
|
||||
*/
|
||||
void timer_disable(timer_dev *dev) {
|
||||
(dev->regs).bas->CR1 = 0;
|
||||
(dev->regs).bas->DIER = 0;
|
||||
switch (dev->type) {
|
||||
case TIMER_ADVANCED: /* fall-through */
|
||||
case TIMER_GENERAL:
|
||||
(dev->regs).gen->CCER = 0;
|
||||
break;
|
||||
case TIMER_BASIC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mode of an individual timer channel.
|
||||
*
|
||||
* Note that not all timers can be configured in every mode. For
|
||||
* example, basic timers cannot be configured to output compare mode.
|
||||
* Be sure to use a timer which is appropriate for the mode you want.
|
||||
*
|
||||
* @param dev Timer whose channel mode to set
|
||||
* @param channel Relevant channel
|
||||
* @param mode New timer mode for channel
|
||||
*/
|
||||
void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
|
||||
ASSERT_FAULT(channel > 0 && channel <= 4);
|
||||
|
||||
/* TODO decide about the basic timers */
|
||||
ASSERT(dev->type != TIMER_BASIC);
|
||||
if (dev->type == TIMER_BASIC)
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
case TIMER_DISABLED:
|
||||
disable_channel(dev, channel);
|
||||
break;
|
||||
case TIMER_PWM:
|
||||
pwm_mode(dev, channel);
|
||||
break;
|
||||
case TIMER_OUTPUT_COMPARE:
|
||||
output_compare_mode(dev, channel);
|
||||
break;
|
||||
//added by CARLOS.
|
||||
case TIMER_ENCODER:
|
||||
encoder_mode(dev, channel); //find a way to pass all the needed stuff on the 8bit var
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine whether a timer has a particular capture/compare channel.
|
||||
*
|
||||
* Different timers have different numbers of capture/compare channels
|
||||
* (and some have none at all). Use this function to test whether a
|
||||
* given timer/channel combination will work.
|
||||
*
|
||||
* @param dev Timer device
|
||||
* @param channel Capture/compare channel, from 1 to 4
|
||||
* @return Nonzero if dev has channel, zero otherwise.
|
||||
*/
|
||||
int timer_has_cc_channel(timer_dev *dev, uint8 channel) {
|
||||
/* On all currently supported series: advanced and "full-featured"
|
||||
* general purpose timers have all four channels. Of the
|
||||
* restricted general timers, timers 9 and 12 have channels 1 and
|
||||
* 2; the others have channel 1 only. Basic timers have none. */
|
||||
rcc_clk_id id = dev->clk_id;
|
||||
ASSERT((1 <= channel) && (channel <= 4));
|
||||
if (id <= RCC_TIMER5 || id == RCC_TIMER8) {
|
||||
return 1; /* 1 and 8 are advanced, 2-5 are "full" general */
|
||||
} else if (id <= RCC_TIMER7) {
|
||||
return 0; /* 6 and 7 are basic */
|
||||
}
|
||||
/* The rest are restricted general. */
|
||||
return (((id == RCC_TIMER9 || id == RCC_TIMER12) && channel <= 2) ||
|
||||
channel == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Attach a timer interrupt.
|
||||
* @param dev Timer device
|
||||
* @param interrupt Interrupt number to attach to; this may be any
|
||||
* timer_interrupt_id or timer_channel value appropriate
|
||||
* for the timer.
|
||||
* @param handler Handler to attach to the given interrupt.
|
||||
* @see timer_interrupt_id
|
||||
* @see timer_channel
|
||||
*/
|
||||
void timer_attach_interrupt(timer_dev *dev,
|
||||
uint8 interrupt,
|
||||
voidFuncPtr handler) {
|
||||
dev->handlers[interrupt] = handler;
|
||||
timer_enable_irq(dev, interrupt);
|
||||
enable_irq(dev, interrupt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detach a timer interrupt.
|
||||
* @param dev Timer device
|
||||
* @param interrupt Interrupt number to detach; this may be any
|
||||
* timer_interrupt_id or timer_channel value appropriate
|
||||
* for the timer.
|
||||
* @see timer_interrupt_id
|
||||
* @see timer_channel
|
||||
*/
|
||||
void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) {
|
||||
timer_disable_irq(dev, interrupt);
|
||||
dev->handlers[interrupt] = NULL;
|
||||
}
|
||||
|
||||
//CARLOS
|
||||
uint8 get_direction(timer_dev *dev){
|
||||
return *bb_perip(&(dev->regs).gen->CR1, TIMER_CR1_DIR_BIT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
static void disable_channel(timer_dev *dev, uint8 channel) {
|
||||
timer_detach_interrupt(dev, channel);
|
||||
timer_cc_disable(dev, channel);
|
||||
}
|
||||
|
||||
static void pwm_mode(timer_dev *dev, uint8 channel) {
|
||||
timer_disable_irq(dev, channel);
|
||||
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
|
||||
timer_cc_enable(dev, channel);
|
||||
}
|
||||
|
||||
static void output_compare_mode(timer_dev *dev, uint8 channel) {
|
||||
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0);
|
||||
timer_cc_enable(dev, channel);
|
||||
}
|
||||
|
||||
//added by CARLOS.
|
||||
static void encoder_mode(timer_dev *dev, uint8 channel) {
|
||||
|
||||
//prescaler.
|
||||
//(dev->regs).gen->PSC = 1;
|
||||
|
||||
//map inputs.
|
||||
(dev->regs).gen->CCMR1 = TIMER_CCMR1_CC1S_INPUT_TI1 | TIMER_CCMR1_CC2S_INPUT_TI2 | TIMER_CCMR1_IC2F | TIMER_CCMR1_IC1F ;
|
||||
|
||||
(dev->regs).gen->SMCR = TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on both edges.
|
||||
|
||||
//polarity
|
||||
//(dev->regs).gen->CCER = TIMER_CCER_CC1P; //to invert the counting, only one of the inputs should be inverted.
|
||||
|
||||
//set the interval used by the encoder.
|
||||
//timer_set_reload(dev, 1000);
|
||||
|
||||
// (dev->regs).gen->CR1 |=TIMER_CR1_UDIS_BIT;
|
||||
|
||||
//run timer
|
||||
timer_resume(dev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
|
||||
static void enable_bas_gen_irq(timer_dev *dev);
|
||||
|
||||
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) {
|
||||
if (dev->type == TIMER_ADVANCED) {
|
||||
enable_adv_irq(dev, iid);
|
||||
} else {
|
||||
enable_bas_gen_irq(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Advanced control timers have several IRQ lines corresponding to
|
||||
* different timer interrupts.
|
||||
*
|
||||
* Note: This function assumes that the only advanced timers are TIM1
|
||||
* and TIM8, and needs the obvious changes if that assumption is
|
||||
* violated by a later STM32 series. */
|
||||
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id) {
|
||||
uint8 is_tim1 = dev->clk_id == RCC_TIMER1;
|
||||
nvic_irq_num irq_num;
|
||||
switch (id) {
|
||||
case TIMER_UPDATE_INTERRUPT:
|
||||
irq_num = (is_tim1 ?
|
||||
NVIC_TIMER1_UP_TIMER10 :
|
||||
NVIC_TIMER8_UP_TIMER13);
|
||||
break;
|
||||
case TIMER_CC1_INTERRUPT: /* Fall through */
|
||||
case TIMER_CC2_INTERRUPT: /* ... */
|
||||
case TIMER_CC3_INTERRUPT: /* ... */
|
||||
case TIMER_CC4_INTERRUPT:
|
||||
irq_num = is_tim1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC;
|
||||
break;
|
||||
case TIMER_COM_INTERRUPT: /* Fall through */
|
||||
case TIMER_TRG_INTERRUPT:
|
||||
irq_num = (is_tim1 ?
|
||||
NVIC_TIMER1_TRG_COM_TIMER11 :
|
||||
NVIC_TIMER8_TRG_COM_TIMER14);
|
||||
break;
|
||||
case TIMER_BREAK_INTERRUPT:
|
||||
irq_num = (is_tim1 ?
|
||||
NVIC_TIMER1_BRK_TIMER9 :
|
||||
NVIC_TIMER8_BRK_TIMER12);
|
||||
break;
|
||||
default:
|
||||
/* Can't happen, but placate the compiler */
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
nvic_irq_enable(irq_num);
|
||||
}
|
||||
|
||||
/* Basic and general purpose timers have a single IRQ line, which is
|
||||
* shared by all interrupts supported by a particular timer. */
|
||||
static void enable_bas_gen_irq(timer_dev *dev) {
|
||||
nvic_irq_num irq_num;
|
||||
switch (dev->clk_id) {
|
||||
case RCC_TIMER2:
|
||||
irq_num = NVIC_TIMER2;
|
||||
break;
|
||||
case RCC_TIMER3:
|
||||
irq_num = NVIC_TIMER3;
|
||||
break;
|
||||
case RCC_TIMER4:
|
||||
irq_num = NVIC_TIMER4;
|
||||
break;
|
||||
case RCC_TIMER5:
|
||||
irq_num = NVIC_TIMER5;
|
||||
break;
|
||||
case RCC_TIMER6:
|
||||
irq_num = NVIC_TIMER6;
|
||||
break;
|
||||
case RCC_TIMER7:
|
||||
irq_num = NVIC_TIMER7;
|
||||
break;
|
||||
case RCC_TIMER9:
|
||||
irq_num = NVIC_TIMER1_BRK_TIMER9;
|
||||
break;
|
||||
case RCC_TIMER10:
|
||||
irq_num = NVIC_TIMER1_UP_TIMER10;
|
||||
break;
|
||||
case RCC_TIMER11:
|
||||
irq_num = NVIC_TIMER1_TRG_COM_TIMER11;
|
||||
break;
|
||||
case RCC_TIMER12:
|
||||
irq_num = NVIC_TIMER8_BRK_TIMER12;
|
||||
break;
|
||||
case RCC_TIMER13:
|
||||
irq_num = NVIC_TIMER8_UP_TIMER13;
|
||||
break;
|
||||
case RCC_TIMER14:
|
||||
irq_num = NVIC_TIMER8_TRG_COM_TIMER14;
|
||||
break;
|
||||
default:
|
||||
ASSERT_FAULT(0);
|
||||
return;
|
||||
}
|
||||
nvic_irq_enable(irq_num);
|
||||
}
|
||||
|
||||
|
||||
/* Note.
|
||||
*
|
||||
* 2015/07/06 Roger Clark
|
||||
*
|
||||
* The IRQ handlers were initially in timer_f1.c however this seems to cause problems
|
||||
* in which the compiler / linker doesn't always link all the required handlers.
|
||||
* The work around was to move the handlers into this file
|
||||
*/
|
||||
|
||||
/*
|
||||
* IRQ handlers
|
||||
*
|
||||
* Defer to the timer_private dispatch API.
|
||||
*
|
||||
* FIXME: The names of these handlers are inaccurate since XL-density
|
||||
* devices came out. Update these to match the STM32F2 names, maybe
|
||||
* using some weak symbol magic to preserve backwards compatibility if
|
||||
* possible. Once that's done, we can just move the IRQ handlers into
|
||||
* the top-level libmaple/timer.c, and there will be no need for this
|
||||
* file.
|
||||
*/
|
||||
|
||||
void __irq_tim1_brk(void) {
|
||||
dispatch_adv_brk(TIMER1);
|
||||
#if STM32_HAVE_TIMER(9)
|
||||
dispatch_tim_9_12(TIMER9);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim1_up(void) {
|
||||
dispatch_adv_up(TIMER1);
|
||||
#if STM32_HAVE_TIMER(10)
|
||||
dispatch_tim_10_11_13_14(TIMER10);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim1_trg_com(void) {
|
||||
dispatch_adv_trg_com(TIMER1);
|
||||
#if STM32_HAVE_TIMER(11)
|
||||
dispatch_tim_10_11_13_14(TIMER11);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim1_cc(void) {
|
||||
dispatch_adv_cc(TIMER1);
|
||||
}
|
||||
|
||||
void __irq_tim2(void) {
|
||||
dispatch_general(TIMER2);
|
||||
}
|
||||
|
||||
void __irq_tim3(void) {
|
||||
dispatch_general(TIMER3);
|
||||
}
|
||||
|
||||
void __irq_tim4(void) {
|
||||
dispatch_general(TIMER4);
|
||||
}
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
void __irq_tim5(void) {
|
||||
dispatch_general(TIMER5);
|
||||
}
|
||||
|
||||
void __irq_tim6(void) {
|
||||
dispatch_basic(TIMER6);
|
||||
}
|
||||
|
||||
void __irq_tim7(void) {
|
||||
dispatch_basic(TIMER7);
|
||||
}
|
||||
|
||||
void __irq_tim8_brk(void) {
|
||||
dispatch_adv_brk(TIMER8);
|
||||
#if STM32_HAVE_TIMER(12)
|
||||
dispatch_tim_9_12(TIMER12);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim8_up(void) {
|
||||
dispatch_adv_up(TIMER8);
|
||||
#if STM32_HAVE_TIMER(13)
|
||||
dispatch_tim_10_11_13_14(TIMER13);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim8_trg_com(void) {
|
||||
dispatch_adv_trg_com(TIMER8);
|
||||
#if STM32_HAVE_TIMER(14)
|
||||
dispatch_tim_10_11_13_14(TIMER14);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __irq_tim8_cc(void) {
|
||||
dispatch_adv_cc(TIMER8);
|
||||
}
|
||||
#endif /* defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) */
|
41
BootLoaders/Boards/stm32/cores/maple/libmaple/timer_f1.c
Normal file
41
BootLoaders/Boards/stm32/cores/maple/libmaple/timer_f1.c
Normal file
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/timer.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief STM32F1 timer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2015/07/06
|
||||
* Note. The IRQ handlers which were initially in this file have been moved to timer.c
|
||||
* to resolve a linker issue in where some IRQ handlers were not being linked even though
|
||||
* they were being used.
|
||||
* This file has been retains for historical reasons, but can be moved at some time in the future
|
||||
* when full testing of the code in the new location has been completed.
|
||||
*/
|
||||
|
152
BootLoaders/Boards/stm32/cores/maple/libmaple/usart.c
Normal file
152
BootLoaders/Boards/stm32/cores/maple/libmaple/usart.c
Normal file
@ -0,0 +1,152 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/usart.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>,
|
||||
* Perry Hung <perry@leaflabs.com>
|
||||
* @brief Portable USART routines
|
||||
*/
|
||||
|
||||
#include <libmaple/usart.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize a serial port.
|
||||
* @param dev Serial port to be initialized
|
||||
*/
|
||||
void usart_init(usart_dev *dev) {
|
||||
rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf);
|
||||
rb_init(dev->wb, USART_TX_BUF_SIZE, dev->tx_buf);
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
nvic_irq_enable(dev->irq_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a serial port.
|
||||
*
|
||||
* USART is enabled in single buffer transmission mode, multibuffer
|
||||
* receiver mode, 8n1.
|
||||
*
|
||||
* Serial port must have a baud rate configured to work properly.
|
||||
*
|
||||
* @param dev Serial port to enable.
|
||||
* @see usart_set_baud_rate()
|
||||
*/
|
||||
void usart_enable(usart_dev *dev) {
|
||||
usart_reg_map *regs = dev->regs;
|
||||
regs->CR1 |= (USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE);// don't change the word length etc, and 'or' in the patten not overwrite |USART_CR1_M_8N1);
|
||||
regs->CR1 |= USART_CR1_UE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn off a serial port.
|
||||
* @param dev Serial port to be disabled
|
||||
*/
|
||||
void usart_disable(usart_dev *dev) {
|
||||
/* FIXME this misbehaves (on F1) if you try to use PWM on TX afterwards */
|
||||
usart_reg_map *regs = dev->regs;
|
||||
|
||||
while(!rb_is_empty(dev->wb))
|
||||
; // wait for TX completed
|
||||
/* TC bit must be high before disabling the USART */
|
||||
while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC))
|
||||
;
|
||||
|
||||
/* Disable UE */
|
||||
regs->CR1 &= ~USART_CR1_UE;
|
||||
|
||||
/* Clean up buffer */
|
||||
usart_reset_rx(dev);
|
||||
usart_reset_tx(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Nonblocking USART transmit
|
||||
* @param dev Serial port to transmit over
|
||||
* @param buf Buffer to transmit
|
||||
* @param len Maximum number of bytes to transmit
|
||||
* @return Number of bytes transmitted
|
||||
*/
|
||||
uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) {
|
||||
usart_reg_map *regs = dev->regs;
|
||||
uint32 txed = 0;
|
||||
while (rb_is_empty(dev->wb) && (regs->SR & USART_SR_TXE) && (txed < len)) {
|
||||
regs->DR = buf[txed++];
|
||||
}
|
||||
regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE while populating the buffer
|
||||
while (txed < len) {
|
||||
if (rb_safe_insert(dev->wb, buf[txed])) {
|
||||
txed++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!rb_is_empty(dev->wb)) {
|
||||
regs->CR1 |= USART_CR1_TXEIE;
|
||||
}
|
||||
return txed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Nonblocking USART receive.
|
||||
* @param dev Serial port to receive bytes from
|
||||
* @param buf Buffer to store received bytes into
|
||||
* @param len Maximum number of bytes to store
|
||||
* @return Number of bytes received
|
||||
*/
|
||||
uint32 usart_rx(usart_dev *dev, uint8 *buf, uint32 len) {
|
||||
uint32 rxed = 0;
|
||||
while (usart_data_available(dev) && rxed < len) {
|
||||
*buf++ = usart_getc(dev);
|
||||
rxed++;
|
||||
}
|
||||
return rxed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmit an unsigned integer to the specified serial port in
|
||||
* decimal format.
|
||||
*
|
||||
* This function blocks until the integer's digits have been
|
||||
* completely transmitted.
|
||||
*
|
||||
* @param dev Serial port to send on
|
||||
* @param val Number to print
|
||||
*/
|
||||
void usart_putudec(usart_dev *dev, uint32 val) {
|
||||
char digits[12];
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
digits[i++] = val % 10 + '0';
|
||||
val /= 10;
|
||||
} while (val > 0);
|
||||
|
||||
while (--i >= 0) {
|
||||
usart_putc(dev, digits[i]);
|
||||
}
|
||||
}
|
225
BootLoaders/Boards/stm32/cores/maple/libmaple/usart_f1.c
Normal file
225
BootLoaders/Boards/stm32/cores/maple/libmaple/usart_f1.c
Normal file
@ -0,0 +1,225 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/stm32f1/usart.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>,
|
||||
* Perry Hung <perry@leaflabs.com>
|
||||
* @brief STM32F1 USART.
|
||||
*/
|
||||
|
||||
#include <libmaple/usart.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include "usart_private.h"
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
|
||||
static ring_buffer usart1_rb;
|
||||
static ring_buffer usart1_wb;
|
||||
static usart_dev usart1 = {
|
||||
.regs = USART1_BASE,
|
||||
.rb = &usart1_rb,
|
||||
.wb = &usart1_wb,
|
||||
.max_baud = 4500000UL,
|
||||
.clk_id = RCC_USART1,
|
||||
.irq_num = NVIC_USART1,
|
||||
};
|
||||
/** USART1 device */
|
||||
usart_dev *USART1 = &usart1;
|
||||
|
||||
static ring_buffer usart2_rb;
|
||||
static ring_buffer usart2_wb;
|
||||
static usart_dev usart2 = {
|
||||
.regs = USART2_BASE,
|
||||
.rb = &usart2_rb,
|
||||
.wb = &usart2_wb,
|
||||
.max_baud = 2250000UL,
|
||||
.clk_id = RCC_USART2,
|
||||
.irq_num = NVIC_USART2,
|
||||
};
|
||||
/** USART2 device */
|
||||
usart_dev *USART2 = &usart2;
|
||||
|
||||
static ring_buffer usart3_rb;
|
||||
static ring_buffer usart3_wb;
|
||||
static usart_dev usart3 = {
|
||||
.regs = USART3_BASE,
|
||||
.rb = &usart3_rb,
|
||||
.wb = &usart3_wb,
|
||||
.max_baud = 2250000UL,
|
||||
.clk_id = RCC_USART3,
|
||||
.irq_num = NVIC_USART3,
|
||||
};
|
||||
/** USART3 device */
|
||||
usart_dev *USART3 = &usart3;
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
static ring_buffer uart4_rb;
|
||||
static ring_buffer uart4_wb;
|
||||
static usart_dev uart4 = {
|
||||
.regs = UART4_BASE,
|
||||
.rb = &uart4_rb,
|
||||
.wb = &uart4_wb,
|
||||
.max_baud = 2250000UL,
|
||||
.clk_id = RCC_UART4,
|
||||
.irq_num = NVIC_UART4,
|
||||
};
|
||||
/** UART4 device */
|
||||
usart_dev *UART4 = &uart4;
|
||||
|
||||
static ring_buffer uart5_rb;
|
||||
static ring_buffer uart5_wb;
|
||||
static usart_dev uart5 = {
|
||||
.regs = UART5_BASE,
|
||||
.rb = &uart5_rb,
|
||||
.wb = &uart5_wb,
|
||||
.max_baud = 2250000UL,
|
||||
.clk_id = RCC_UART5,
|
||||
.irq_num = NVIC_UART5,
|
||||
};
|
||||
/** UART5 device */
|
||||
usart_dev *UART5 = &uart5;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
void usart_config_gpios_async(usart_dev *udev,
|
||||
gpio_dev *rx_dev, uint8 rx,
|
||||
gpio_dev *tx_dev, uint8 tx,
|
||||
unsigned flags) {
|
||||
gpio_set_mode(rx_dev, rx, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(tx_dev, tx, GPIO_AF_OUTPUT_PP);
|
||||
/*
|
||||
CR1 bit 12 Word length 0=8 1=9
|
||||
CR1 bit 11 wake (default value is 0) we can safely set this value to 0 (zero) each time
|
||||
CR1 bit 10 parity enable (1 = enabled)
|
||||
CR1 bit 9 Parity selection 0 = Even 1 = Odd
|
||||
CR2 bits 13 and 12 00 = 1 01 = 0.5 10 = 2 11 = 1.5
|
||||
Not all USARTs support 1.5 or 0.5 bits so its best to avoid them.
|
||||
When parity enabled the word length must be increased (CR1 bit 12 set).
|
||||
Word length of 9 bit with parity is not supported.
|
||||
CR2 CR1
|
||||
0B00 0000
|
||||
0B10 0000
|
||||
0B00 1000
|
||||
0B10 1000
|
||||
|
||||
0B00 0010
|
||||
0B10 0010
|
||||
0B00 1010
|
||||
0B10 1010
|
||||
|
||||
0B00 0011
|
||||
0B10 0011
|
||||
0B00 1011
|
||||
0B10 1011
|
||||
|
||||
#define SERIAL_8N1 0B 0000 0000
|
||||
#define SERIAL_8N2 0B 0010 0000
|
||||
#define SERIAL_9N1 0B 0000 1000
|
||||
#define SERIAL_9N2 0B 0010 1000
|
||||
|
||||
#define SERIAL_8E1 0B 0000 1010
|
||||
#define SERIAL_8E2 0B 0010 1010
|
||||
//#define SERIAL_9E1 0B 0000 1010
|
||||
//#define SERIAL_9E2 0B 0010 1010
|
||||
|
||||
#define SERIAL_8O1 0B 0000 1011
|
||||
#define SERIAL_8O2 0B 0010 1011
|
||||
//#define SERIAL_9O1 0B 0000 1011
|
||||
//#define SERIAL_9O2 0B 0010 1011
|
||||
*/
|
||||
|
||||
udev->regs->CR1 = (udev->regs->CR1 & 0B1110000111111111) | ((uint32_t)(flags&0x0F)<<9);
|
||||
udev->regs->CR2 = (udev->regs->CR2 & 0B1100111111111111) | ((uint32_t)(flags&0x30)<<8);
|
||||
}
|
||||
|
||||
void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud) {
|
||||
uint32 integer_part;
|
||||
uint32 fractional_part;
|
||||
uint32 tmp;
|
||||
|
||||
/* Figure out the clock speed, if the user doesn't give one. */
|
||||
if (clock_speed == 0) {
|
||||
clock_speed = _usart_clock_freq(dev);
|
||||
}
|
||||
ASSERT(clock_speed);
|
||||
|
||||
/* Convert desired baud rate to baud rate register setting. */
|
||||
integer_part = (25 * clock_speed) / (4 * baud);
|
||||
tmp = (integer_part / 100) << 4;
|
||||
fractional_part = integer_part - (100 * (tmp >> 4));
|
||||
tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F);
|
||||
|
||||
dev->regs->BRR = (uint16)tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call a function on each USART.
|
||||
* @param fn Function to call.
|
||||
*/
|
||||
void usart_foreach(void (*fn)(usart_dev*)) {
|
||||
fn(USART1);
|
||||
fn(USART2);
|
||||
fn(USART3);
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
fn(UART4);
|
||||
fn(UART5);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handlers.
|
||||
*/
|
||||
|
||||
void __irq_usart1(void) {
|
||||
usart_irq(&usart1_rb, &usart1_wb, USART1_BASE);
|
||||
}
|
||||
|
||||
/*
|
||||
void __irq_usart2(void) {
|
||||
usart_irq(&usart2_rb, &usart2_wb, USART2_BASE);
|
||||
}
|
||||
|
||||
void __irq_usart3(void) {
|
||||
usart_irq(&usart3_rb, &usart3_wb, USART3_BASE);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
void __irq_uart4(void) {
|
||||
usart_irq(&uart4_rb, &uart4_wb, UART4_BASE);
|
||||
}
|
||||
|
||||
void __irq_uart5(void) {
|
||||
usart_irq(&uart5_rb, &uart5_wb, UART5_BASE);
|
||||
}
|
||||
#endif
|
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/usart_private.c
|
||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||
* @brief Private USART routines.
|
||||
*/
|
||||
|
||||
#include "usart_private.h"
|
||||
#include <libmaple/rcc.h>
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
uint32 _usart_clock_freq(usart_dev *dev) {
|
||||
rcc_clk_domain domain = rcc_dev_clk(dev->clk_id);
|
||||
return (domain == RCC_APB1 ? STM32_PCLK1 :
|
||||
(domain == RCC_APB2 ? STM32_PCLK2 : 0));
|
||||
}
|
63
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/README
Normal file
63
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/README
Normal file
@ -0,0 +1,63 @@
|
||||
The USB submodule of libmaple is a separate piece of the codebase for
|
||||
reasons that are largely historical.
|
||||
|
||||
Current Status:
|
||||
|
||||
There's only support for the USB device peripheral found on
|
||||
STM32F103s.
|
||||
|
||||
We rely on the low level core library provided by ST to implement
|
||||
the USB transfer protocol for control endpoint transfers.
|
||||
|
||||
The virtual com port (which is exposed via
|
||||
<libmaple/usb_cdcacm.h>) serves two important purposes.
|
||||
|
||||
1) It allows serial data transfers between user sketches an a
|
||||
host computer.
|
||||
|
||||
2) It allows the host PC to issue a system reset into the DFU
|
||||
bootloader with the DTR + RTS + "1EAF" sequence (see
|
||||
leaflabs.com/docs/bootloader.html for more information on
|
||||
this).
|
||||
|
||||
After reset, Maple will run the DFU bootloader for a few seconds,
|
||||
during which the user can begin a DFU upload operation (uploads
|
||||
application binary into RAM/FLASH). Thus, without this virtual com
|
||||
port, it would be necessary to find an alternative means to reset
|
||||
the chip in order to enable the bootloader.
|
||||
|
||||
If you would like to develop your own USB application for whatever
|
||||
reason (e.g. to use faster isochronous enpoints for streaming
|
||||
audio, or implement the USB HID or Mass Storage specs), then
|
||||
ensure that you leave some hook for resetting Maple remotely in
|
||||
order to spin up the DFU bootloader. Please make sure to get
|
||||
yourself a unique vendor/product ID pair for your application, as
|
||||
some operating systems will assign a host-side driver based on
|
||||
these tags.
|
||||
|
||||
It would be possible to build a compound USB device, that
|
||||
implements endpoints for both the virtual COM port as well as some
|
||||
other components (mass storage etc.). However, this turns out to
|
||||
be a burden from the host driver side, as Windows and *nix handle
|
||||
compound USB devices quite differently.
|
||||
|
||||
Be mindful that enabling the USB peripheral isn't "free." The
|
||||
device must respond to periodic bus activity (every few
|
||||
milliseconds) by servicing an ISR. Therefore, the USB application
|
||||
should be disabled inside of timing critical applications.
|
||||
|
||||
In order to disconnect the device from the host, a USB_DISC pin is
|
||||
asserted (e.g. on Maple, this is PC12). Alternatively, the NVIC
|
||||
can be directly configured to disable the USB LP/HP IRQ's.
|
||||
|
||||
The files inside of usb_lib were provided by ST and are subject to
|
||||
their own license, all other files were written by the LeafLabs
|
||||
team and fall under the MIT license.
|
||||
|
||||
TODO:
|
||||
|
||||
- Generic USB driver core with series-provided backends, like
|
||||
libopencm3 has.
|
||||
- Strip out ST code.
|
||||
- Integration with a high level USB library (like LUFA/MyUSB) to
|
||||
allow users to write custom USB applications.
|
45
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/rules.mk
Normal file
45
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/rules.mk
Normal file
@ -0,0 +1,45 @@
|
||||
# Standard things
|
||||
sp := $(sp).x
|
||||
dirstack_$(sp) := $(d)
|
||||
d := $(dir)
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)
|
||||
|
||||
# Local flags
|
||||
CFLAGS_$(d) = -I$(d) -I$(d)/$(MCU_SERIES) -I$(d)/usb_lib $(LIBMAPLE_INCLUDES) $(LIBMAPLE_PRIVATE_INCLUDES) -Wall
|
||||
|
||||
# Add usblib and series subdirectory to BUILDDIRS.
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES)
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usb_lib
|
||||
|
||||
# Local rules and targets
|
||||
sSRCS_$(d) :=
|
||||
cSRCS_$(d) :=
|
||||
# We currently only have F1 performance line support. Sigh.
|
||||
ifeq ($(MCU_SERIES), stm32f1)
|
||||
ifeq ($(MCU_F1_LINE), performance)
|
||||
cSRCS_$(d) += $(MCU_SERIES)/usb.c
|
||||
cSRCS_$(d) += $(MCU_SERIES)/usb_reg_map.c
|
||||
cSRCS_$(d) += $(MCU_SERIES)/usb_cdcacm.c
|
||||
cSRCS_$(d) += usb_lib/usb_core.c
|
||||
cSRCS_$(d) += usb_lib/usb_init.c
|
||||
cSRCS_$(d) += usb_lib/usb_mem.c
|
||||
cSRCS_$(d) += usb_lib/usb_regs.c
|
||||
endif
|
||||
endif
|
||||
|
||||
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
|
||||
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
|
||||
|
||||
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
|
||||
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o)
|
||||
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
|
||||
|
||||
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
|
||||
$(OBJS_$(d)): TGT_ASFLAGS :=
|
||||
|
||||
TGT_BIN += $(OBJS_$(d))
|
||||
|
||||
# Standard things
|
||||
-include $(DEPS_$(d))
|
||||
d := $(dirstack_$(sp))
|
||||
sp := $(basename $(sp))
|
387
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/stm32f1/usb.c
Normal file
387
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/stm32f1/usb.c
Normal file
@ -0,0 +1,387 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/usb/stm32f1/usb.c
|
||||
* @brief USB support.
|
||||
*
|
||||
* This is a mess.
|
||||
*/
|
||||
|
||||
#include <libmaple/usb.h>
|
||||
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/rcc.h>
|
||||
|
||||
/* Private headers */
|
||||
#include "usb_reg_map.h"
|
||||
#include "usb_lib_globals.h"
|
||||
|
||||
/* usb_lib headers */
|
||||
#include "usb_type.h"
|
||||
#include "usb_core.h"
|
||||
|
||||
static void dispatch_ctr_lp(void);
|
||||
|
||||
/*
|
||||
* usb_lib/ globals
|
||||
*/
|
||||
|
||||
uint16 SaveTState; /* caches TX status for later use */
|
||||
uint16 SaveRState; /* caches RX status for later use */
|
||||
|
||||
/*
|
||||
* Other state
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RESUME_EXTERNAL,
|
||||
RESUME_INTERNAL,
|
||||
RESUME_LATER,
|
||||
RESUME_WAIT,
|
||||
RESUME_START,
|
||||
RESUME_ON,
|
||||
RESUME_OFF,
|
||||
RESUME_ESOF
|
||||
} RESUME_STATE;
|
||||
|
||||
struct {
|
||||
volatile RESUME_STATE eState;
|
||||
volatile uint8 bESOFcnt;
|
||||
} ResumeS;
|
||||
|
||||
static usblib_dev usblib = {
|
||||
.irq_mask = USB_ISR_MSK,
|
||||
.state = USB_UNCONNECTED,
|
||||
.prevState = USB_UNCONNECTED,
|
||||
.clk_id = RCC_USB,
|
||||
};
|
||||
usblib_dev *USBLIB = &usblib;
|
||||
|
||||
/*
|
||||
* Routines
|
||||
*/
|
||||
|
||||
void usb_init_usblib(usblib_dev *dev,
|
||||
void (**ep_int_in)(void),
|
||||
void (**ep_int_out)(void)) {
|
||||
rcc_clk_enable(dev->clk_id);
|
||||
|
||||
dev->ep_int_in = ep_int_in;
|
||||
dev->ep_int_out = ep_int_out;
|
||||
|
||||
/* usb_lib/ declares both and then assumes that pFoo points to Foo
|
||||
* (even though the names don't always match), which is stupid for
|
||||
* all of the obvious reasons, but whatever. Here we are. */
|
||||
pInformation = &Device_Info;
|
||||
pProperty = &Device_Property;
|
||||
pUser_Standard_Requests = &User_Standard_Requests;
|
||||
|
||||
pInformation->ControlState = 2; /* FIXME [0.0.12] use
|
||||
CONTROL_STATE enumerator */
|
||||
pProperty->Init();
|
||||
}
|
||||
|
||||
static void usb_suspend(void) {
|
||||
uint16 cntr;
|
||||
|
||||
/* TODO decide if read/modify/write is really what we want
|
||||
* (e.g. usb_resume_init() reconfigures CNTR). */
|
||||
cntr = USB_BASE->CNTR;
|
||||
cntr |= USB_CNTR_FSUSP;
|
||||
USB_BASE->CNTR = cntr;
|
||||
cntr |= USB_CNTR_LP_MODE;
|
||||
USB_BASE->CNTR = cntr;
|
||||
|
||||
USBLIB->prevState = USBLIB->state;
|
||||
USBLIB->state = USB_SUSPENDED;
|
||||
}
|
||||
|
||||
static void usb_resume_init(void) {
|
||||
uint16 cntr;
|
||||
|
||||
cntr = USB_BASE->CNTR;
|
||||
cntr &= ~USB_CNTR_LP_MODE;
|
||||
USB_BASE->CNTR = cntr;
|
||||
|
||||
/* Enable interrupt lines */
|
||||
USB_BASE->CNTR = USB_ISR_MSK;
|
||||
}
|
||||
|
||||
static void usb_resume(RESUME_STATE eResumeSetVal) {
|
||||
uint16 cntr;
|
||||
|
||||
if (eResumeSetVal != RESUME_ESOF) {
|
||||
ResumeS.eState = eResumeSetVal;
|
||||
}
|
||||
|
||||
switch (ResumeS.eState) {
|
||||
case RESUME_EXTERNAL:
|
||||
usb_resume_init();
|
||||
ResumeS.eState = RESUME_OFF;
|
||||
USBLIB->state = USBLIB->prevState;
|
||||
break;
|
||||
case RESUME_INTERNAL:
|
||||
usb_resume_init();
|
||||
ResumeS.eState = RESUME_START;
|
||||
break;
|
||||
case RESUME_LATER:
|
||||
ResumeS.bESOFcnt = 2;
|
||||
ResumeS.eState = RESUME_WAIT;
|
||||
break;
|
||||
case RESUME_WAIT:
|
||||
ResumeS.bESOFcnt--;
|
||||
if (ResumeS.bESOFcnt == 0) {
|
||||
ResumeS.eState = RESUME_START;
|
||||
}
|
||||
break;
|
||||
case RESUME_START:
|
||||
cntr = USB_BASE->CNTR;
|
||||
cntr |= USB_CNTR_RESUME;
|
||||
USB_BASE->CNTR = cntr;
|
||||
ResumeS.eState = RESUME_ON;
|
||||
ResumeS.bESOFcnt = 10;
|
||||
break;
|
||||
case RESUME_ON:
|
||||
ResumeS.bESOFcnt--;
|
||||
if (ResumeS.bESOFcnt == 0) {
|
||||
cntr = USB_BASE->CNTR;
|
||||
cntr &= ~USB_CNTR_RESUME;
|
||||
USB_BASE->CNTR = cntr;
|
||||
USBLIB->state = USBLIB->prevState;
|
||||
ResumeS.eState = RESUME_OFF;
|
||||
}
|
||||
break;
|
||||
case RESUME_OFF:
|
||||
case RESUME_ESOF:
|
||||
default:
|
||||
ResumeS.eState = RESUME_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define SUSPEND_ENABLED 1
|
||||
void __irq_usb_lp_can_rx0(void) {
|
||||
uint16 istr = USB_BASE->ISTR;
|
||||
|
||||
/* Use USB_ISR_MSK to only include code for bits we care about. */
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_RESET)
|
||||
if (istr & USB_ISTR_RESET & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~USB_ISTR_RESET;
|
||||
pProperty->Reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_PMAOVR)
|
||||
if (istr & ISTR_PMAOVR & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~USB_ISTR_PMAOVR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_ERR)
|
||||
if (istr & USB_ISTR_ERR & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~USB_ISTR_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_WKUP)
|
||||
if (istr & USB_ISTR_WKUP & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~(USB_ISTR_WKUP | USB_ISTR_SUSP);
|
||||
usb_resume(RESUME_EXTERNAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_SUSP)
|
||||
if (istr & USB_ISTR_SUSP & USBLIB->irq_mask) {
|
||||
/* check if SUSPEND is possible */
|
||||
if (SUSPEND_ENABLED) {
|
||||
usb_suspend();
|
||||
} else {
|
||||
/* if not possible then resume after xx ms */
|
||||
usb_resume(RESUME_LATER);
|
||||
}
|
||||
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
|
||||
USB_BASE->ISTR = ~(USB_ISTR_WKUP | USB_ISTR_SUSP);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_SOF)
|
||||
if (istr & USB_ISTR_SOF & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~USB_ISTR_SOF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_ESOF)
|
||||
if (istr & USB_ISTR_ESOF & USBLIB->irq_mask) {
|
||||
USB_BASE->ISTR = ~USB_ISTR_ESOF;
|
||||
/* resume handling timing is made with ESOFs */
|
||||
usb_resume(RESUME_ESOF); /* request without change of the machine state */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Service the correct transfer interrupt.
|
||||
*/
|
||||
|
||||
#if (USB_ISR_MSK & USB_ISTR_CTR)
|
||||
if (istr & USB_ISTR_CTR & USBLIB->irq_mask) {
|
||||
dispatch_ctr_lp();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary routines
|
||||
*/
|
||||
|
||||
static inline uint8 dispatch_endpt_zero(uint16 istr_dir);
|
||||
static inline void dispatch_endpt(uint8 ep);
|
||||
static inline void set_rx_tx_status0(uint16 rx, uint16 tx);
|
||||
|
||||
static void handle_setup0(void);
|
||||
static void handle_in0(void);
|
||||
static void handle_out0(void);
|
||||
|
||||
static void dispatch_ctr_lp() {
|
||||
uint16 istr;
|
||||
while (((istr = USB_BASE->ISTR) & USB_ISTR_CTR) != 0) {
|
||||
/* TODO WTF, figure this out: RM0008 says CTR is read-only,
|
||||
* but ST's firmware claims it's clear-only, and emphasizes
|
||||
* the importance of clearing it in more than one place. */
|
||||
USB_BASE->ISTR = ~USB_ISTR_CTR;
|
||||
uint8 ep_id = istr & USB_ISTR_EP_ID;
|
||||
if (ep_id == 0) {
|
||||
/* TODO figure out why it's OK to break out of the loop
|
||||
* once we're done serving endpoint zero, but not okay if
|
||||
* there are multiple nonzero endpoint transfers to
|
||||
* handle. */
|
||||
if (dispatch_endpt_zero(istr & USB_ISTR_DIR)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dispatch_endpt(ep_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME Dataflow on endpoint 0 RX/TX status is based off of ST's
|
||||
* code, and is ugly/confusing in its use of SaveRState/SaveTState.
|
||||
* Fixing this requires filling in handle_in0(), handle_setup0(),
|
||||
* handle_out0(). */
|
||||
static inline uint8 dispatch_endpt_zero(uint16 istr_dir) {
|
||||
uint32 epr = (uint16)USB_BASE->EP[0];
|
||||
|
||||
if (!(epr & (USB_EP_CTR_TX | USB_EP_SETUP | USB_EP_CTR_RX))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cache RX/TX statuses in SaveRState/SaveTState, respectively.
|
||||
* The various handle_foo0() may clobber these values
|
||||
* before we reset them at the end of this routine. */
|
||||
SaveRState = epr & USB_EP_STAT_RX;
|
||||
SaveTState = epr & USB_EP_STAT_TX;
|
||||
|
||||
/* Set actual RX/TX statuses to NAK while we're thinking */
|
||||
set_rx_tx_status0(USB_EP_STAT_RX_NAK, USB_EP_STAT_TX_NAK);
|
||||
|
||||
if (istr_dir == 0) {
|
||||
/* ST RM0008: "If DIR bit=0, CTR_TX bit is set in the USB_EPnR
|
||||
* register related to the interrupting endpoint. The
|
||||
* interrupting transaction is of IN type (data transmitted by
|
||||
* the USB peripheral to the host PC)." */
|
||||
ASSERT_FAULT(epr & USB_EP_CTR_TX);
|
||||
usb_clear_ctr_tx(USB_EP0);
|
||||
handle_in0();
|
||||
} else {
|
||||
/* RM0008: "If DIR bit=1, CTR_RX bit or both CTR_TX/CTR_RX
|
||||
* are set in the USB_EPnR register related to the
|
||||
* interrupting endpoint. The interrupting transaction is of
|
||||
* OUT type (data received by the USB peripheral from the host
|
||||
* PC) or two pending transactions are waiting to be
|
||||
* processed."
|
||||
*
|
||||
* [mbolivar] Note how the following control flow (which
|
||||
* replicates ST's) doesn't seem to actually handle both
|
||||
* interrupts that are ostensibly pending when both CTR_RX and
|
||||
* CTR_TX are set.
|
||||
*
|
||||
* TODO sort this mess out.
|
||||
*/
|
||||
if (epr & USB_EP_CTR_TX) {
|
||||
usb_clear_ctr_tx(USB_EP0);
|
||||
handle_in0();
|
||||
} else { /* SETUP or CTR_RX */
|
||||
/* SETUP is held constant while CTR_RX is set, so clear it
|
||||
* either way */
|
||||
usb_clear_ctr_rx(USB_EP0);
|
||||
if (epr & USB_EP_SETUP) {
|
||||
handle_setup0();
|
||||
} else { /* CTR_RX */
|
||||
handle_out0();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_rx_tx_status0(SaveRState, SaveTState);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void dispatch_endpt(uint8 ep) {
|
||||
uint32 epr = USB_BASE->EP[ep];
|
||||
/* If ISTR_CTR is set and the ISTR gave us this EP_ID to handle,
|
||||
* then presumably at least one of CTR_RX and CTR_TX is set, but
|
||||
* again, ST's control flow allows for the possibility of neither.
|
||||
*
|
||||
* TODO try to find out if neither being set is possible. */
|
||||
if (epr & USB_EP_CTR_RX) {
|
||||
usb_clear_ctr_rx(ep);
|
||||
(USBLIB->ep_int_out[ep - 1])();
|
||||
}
|
||||
if (epr & USB_EP_CTR_TX) {
|
||||
usb_clear_ctr_tx(ep);
|
||||
(USBLIB->ep_int_in[ep - 1])();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_rx_tx_status0(uint16 rx, uint16 tx) {
|
||||
usb_set_ep_rx_stat(USB_EP0, rx);
|
||||
usb_set_ep_tx_stat(USB_EP0, tx);
|
||||
}
|
||||
|
||||
/* TODO Rip out usb_lib/ dependency from the following functions: */
|
||||
|
||||
static void handle_setup0(void) {
|
||||
Setup0_Process();
|
||||
}
|
||||
|
||||
static void handle_in0(void) {
|
||||
In0_Process();
|
||||
}
|
||||
|
||||
static void handle_out0(void) {
|
||||
Out0_Process();
|
||||
}
|
@ -0,0 +1,809 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 LeafLabs LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/usb/stm32f1/usb_cdcacm.c
|
||||
* @brief USB CDC ACM (a.k.a. virtual serial terminal, VCOM).
|
||||
*
|
||||
* FIXME: this works on the STM32F1 USB peripherals, and probably no
|
||||
* place else. Nonportable bits really need to be factored out, and
|
||||
* the result made cleaner.
|
||||
*/
|
||||
|
||||
#include <libmaple/usb_cdcacm.h>
|
||||
|
||||
#include <libmaple/usb.h>
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/delay.h>
|
||||
|
||||
/* Private headers */
|
||||
#include "usb_lib_globals.h"
|
||||
#include "usb_reg_map.h"
|
||||
|
||||
/* usb_lib headers */
|
||||
#include "usb_type.h"
|
||||
#include "usb_core.h"
|
||||
#include "usb_def.h"
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
***
|
||||
*** HACK ALERT! FIXME FIXME FIXME FIXME!
|
||||
***
|
||||
*** A bunch of LeafLabs-specific configuration lives in here for
|
||||
*** now. This mess REALLY needs to get teased apart, with
|
||||
*** appropriate pieces moved into Wirish.
|
||||
***
|
||||
******************************************************************************
|
||||
*****************************************************************************/
|
||||
|
||||
#if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \
|
||||
defined(BOARD_maple_mini) || defined(BOARD_maple_native))
|
||||
//#warning USB CDC ACM relies on LeafLabs board-specific configuration.\
|
||||
// You may have problems on non-LeafLabs boards.
|
||||
#endif
|
||||
|
||||
static void vcomDataTxCb(void);
|
||||
static void vcomDataRxCb(void);
|
||||
static uint8* vcomGetSetLineCoding(uint16);
|
||||
|
||||
static void usbInit(void);
|
||||
static void usbReset(void);
|
||||
static RESULT usbDataSetup(uint8 request);
|
||||
static RESULT usbNoDataSetup(uint8 request);
|
||||
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting);
|
||||
static uint8* usbGetDeviceDescriptor(uint16 length);
|
||||
static uint8* usbGetConfigDescriptor(uint16 length);
|
||||
static uint8* usbGetStringDescriptor(uint16 length);
|
||||
static void usbSetConfiguration(void);
|
||||
static void usbSetDeviceAddress(void);
|
||||
|
||||
/*
|
||||
* Descriptors
|
||||
*/
|
||||
|
||||
/* FIXME move to Wirish */
|
||||
#define LEAFLABS_ID_VENDOR 0x1EAF
|
||||
#define MAPLE_ID_PRODUCT 0x0004
|
||||
static const usb_descriptor_device usbVcomDescriptor_Device =
|
||||
USB_CDCACM_DECLARE_DEV_DESC(LEAFLABS_ID_VENDOR, MAPLE_ID_PRODUCT);
|
||||
|
||||
typedef struct {
|
||||
usb_descriptor_config_header Config_Header;
|
||||
usb_descriptor_interface CCI_Interface;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_ACM;
|
||||
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
|
||||
usb_descriptor_endpoint ManagementEndpoint;
|
||||
usb_descriptor_interface DCI_Interface;
|
||||
usb_descriptor_endpoint DataOutEndpoint;
|
||||
usb_descriptor_endpoint DataInEndpoint;
|
||||
} __packed usb_descriptor_config;
|
||||
|
||||
#define MAX_POWER (100 >> 1)
|
||||
static const usb_descriptor_config usbVcomDescriptor_Config = {
|
||||
.Config_Header = {
|
||||
.bLength = sizeof(usb_descriptor_config_header),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
|
||||
.wTotalLength = sizeof(usb_descriptor_config),
|
||||
.bNumInterfaces = 0x02,
|
||||
.bConfigurationValue = 0x01,
|
||||
.iConfiguration = 0x00,
|
||||
.bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED |
|
||||
USB_CONFIG_ATTR_SELF_POWERED),
|
||||
.bMaxPower = MAX_POWER,
|
||||
},
|
||||
|
||||
.CCI_Interface = {
|
||||
.bLength = sizeof(usb_descriptor_interface),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 0x00,
|
||||
.bAlternateSetting = 0x00,
|
||||
.bNumEndpoints = 0x01,
|
||||
.bInterfaceClass = USB_INTERFACE_CLASS_CDC,
|
||||
.bInterfaceSubClass = USB_INTERFACE_SUBCLASS_CDC_ACM,
|
||||
.bInterfaceProtocol = 0x01, /* Common AT Commands */
|
||||
.iInterface = 0x00,
|
||||
},
|
||||
|
||||
.CDC_Functional_IntHeader = {
|
||||
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
|
||||
.bDescriptorType = 0x24,
|
||||
.SubType = 0x00,
|
||||
.Data = {0x01, 0x10},
|
||||
},
|
||||
|
||||
.CDC_Functional_CallManagement = {
|
||||
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
|
||||
.bDescriptorType = 0x24,
|
||||
.SubType = 0x01,
|
||||
.Data = {0x03, 0x01},
|
||||
},
|
||||
|
||||
.CDC_Functional_ACM = {
|
||||
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(1),
|
||||
.bDescriptorType = 0x24,
|
||||
.SubType = 0x02,
|
||||
.Data = {0x06},
|
||||
},
|
||||
|
||||
.CDC_Functional_Union = {
|
||||
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
|
||||
.bDescriptorType = 0x24,
|
||||
.SubType = 0x06,
|
||||
.Data = {0x00, 0x01},
|
||||
},
|
||||
|
||||
.ManagementEndpoint = {
|
||||
.bLength = sizeof(usb_descriptor_endpoint),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN |
|
||||
USB_CDCACM_MANAGEMENT_ENDP),
|
||||
.bmAttributes = USB_EP_TYPE_INTERRUPT,
|
||||
.wMaxPacketSize = USB_CDCACM_MANAGEMENT_EPSIZE,
|
||||
.bInterval = 0xFF,
|
||||
},
|
||||
|
||||
.DCI_Interface = {
|
||||
.bLength = sizeof(usb_descriptor_interface),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 0x01,
|
||||
.bAlternateSetting = 0x00,
|
||||
.bNumEndpoints = 0x02,
|
||||
.bInterfaceClass = USB_INTERFACE_CLASS_DIC,
|
||||
.bInterfaceSubClass = 0x00, /* None */
|
||||
.bInterfaceProtocol = 0x00, /* None */
|
||||
.iInterface = 0x00,
|
||||
},
|
||||
|
||||
.DataOutEndpoint = {
|
||||
.bLength = sizeof(usb_descriptor_endpoint),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT |
|
||||
USB_CDCACM_RX_ENDP),
|
||||
.bmAttributes = USB_EP_TYPE_BULK,
|
||||
.wMaxPacketSize = USB_CDCACM_RX_EPSIZE,
|
||||
.bInterval = 0x00,
|
||||
},
|
||||
|
||||
.DataInEndpoint = {
|
||||
.bLength = sizeof(usb_descriptor_endpoint),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | USB_CDCACM_TX_ENDP),
|
||||
.bmAttributes = USB_EP_TYPE_BULK,
|
||||
.wMaxPacketSize = USB_CDCACM_TX_EPSIZE,
|
||||
.bInterval = 0x00,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
String Descriptors:
|
||||
|
||||
we may choose to specify any or none of the following string
|
||||
identifiers:
|
||||
|
||||
iManufacturer: LeafLabs
|
||||
iProduct: Maple
|
||||
iSerialNumber: NONE
|
||||
iConfiguration: NONE
|
||||
iInterface(CCI): NONE
|
||||
iInterface(DCI): NONE
|
||||
|
||||
*/
|
||||
|
||||
/* Unicode language identifier: 0x0409 is US English */
|
||||
/* FIXME move to Wirish */
|
||||
static const usb_descriptor_string usbVcomDescriptor_LangID = {
|
||||
.bLength = USB_DESCRIPTOR_STRING_LEN(1),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
|
||||
.bString = {0x09, 0x04},
|
||||
};
|
||||
|
||||
/* FIXME move to Wirish */
|
||||
static const usb_descriptor_string usbVcomDescriptor_iManufacturer = {
|
||||
.bLength = USB_DESCRIPTOR_STRING_LEN(8),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
|
||||
.bString = {'L', 0, 'e', 0, 'a', 0, 'f', 0,
|
||||
'L', 0, 'a', 0, 'b', 0, 's', 0},
|
||||
};
|
||||
|
||||
/* FIXME move to Wirish */
|
||||
static const usb_descriptor_string usbVcomDescriptor_iProduct = {
|
||||
.bLength = USB_DESCRIPTOR_STRING_LEN(5),
|
||||
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
|
||||
.bString = {'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0},
|
||||
};
|
||||
|
||||
static ONE_DESCRIPTOR Device_Descriptor = {
|
||||
(uint8*)&usbVcomDescriptor_Device,
|
||||
sizeof(usb_descriptor_device)
|
||||
};
|
||||
|
||||
static ONE_DESCRIPTOR Config_Descriptor = {
|
||||
(uint8*)&usbVcomDescriptor_Config,
|
||||
sizeof(usb_descriptor_config)
|
||||
};
|
||||
|
||||
#define N_STRING_DESCRIPTORS 3
|
||||
static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = {
|
||||
{(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)},
|
||||
{(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)},
|
||||
{(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(5)}
|
||||
};
|
||||
|
||||
/*
|
||||
* Etc.
|
||||
*/
|
||||
|
||||
/* I/O state */
|
||||
|
||||
#define CDC_SERIAL_RX_BUFFER_SIZE 256 // must be power of 2
|
||||
#define CDC_SERIAL_RX_BUFFER_SIZE_MASK (CDC_SERIAL_RX_BUFFER_SIZE-1)
|
||||
|
||||
/* Received data */
|
||||
static volatile uint8 vcomBufferRx[CDC_SERIAL_RX_BUFFER_SIZE];
|
||||
/* Write index to vcomBufferRx */
|
||||
static volatile uint32 rx_head;
|
||||
/* Read index from vcomBufferRx */
|
||||
static volatile uint32 rx_tail;
|
||||
|
||||
#define CDC_SERIAL_TX_BUFFER_SIZE 256 // must be power of 2
|
||||
#define CDC_SERIAL_TX_BUFFER_SIZE_MASK (CDC_SERIAL_TX_BUFFER_SIZE-1)
|
||||
// Tx data
|
||||
static volatile uint8 vcomBufferTx[CDC_SERIAL_TX_BUFFER_SIZE];
|
||||
// Write index to vcomBufferTx
|
||||
static volatile uint32 tx_head;
|
||||
// Read index from vcomBufferTx
|
||||
static volatile uint32 tx_tail;
|
||||
// Are we currently sending an IN packet?
|
||||
static volatile int8 transmitting;
|
||||
|
||||
|
||||
|
||||
/* Other state (line coding, DTR/RTS) */
|
||||
|
||||
static volatile usb_cdcacm_line_coding line_coding = {
|
||||
/* This default is 115200 baud, 8N1. */
|
||||
.dwDTERate = 115200,
|
||||
.bCharFormat = USB_CDCACM_STOP_BITS_1,
|
||||
.bParityType = USB_CDCACM_PARITY_NONE,
|
||||
.bDataBits = 8,
|
||||
};
|
||||
|
||||
/* DTR in bit 0, RTS in bit 1. */
|
||||
static volatile uint8 line_dtr_rts = 0;
|
||||
|
||||
/*
|
||||
* Endpoint callbacks
|
||||
*/
|
||||
|
||||
static void (*ep_int_in[7])(void) =
|
||||
{vcomDataTxCb,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process};
|
||||
|
||||
static void (*ep_int_out[7])(void) =
|
||||
{NOP_Process,
|
||||
NOP_Process,
|
||||
vcomDataRxCb,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process,
|
||||
NOP_Process};
|
||||
|
||||
/*
|
||||
* Globals required by usb_lib/
|
||||
*
|
||||
* Mark these weak so they can be overriden to implement other USB
|
||||
* functionality.
|
||||
*/
|
||||
|
||||
#define NUM_ENDPTS 0x04
|
||||
__weak DEVICE Device_Table = {
|
||||
.Total_Endpoint = NUM_ENDPTS,
|
||||
.Total_Configuration = 1
|
||||
};
|
||||
|
||||
#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */
|
||||
__weak DEVICE_PROP Device_Property = {
|
||||
.Init = usbInit,
|
||||
.Reset = usbReset,
|
||||
.Process_Status_IN = NOP_Process,
|
||||
.Process_Status_OUT = NOP_Process,
|
||||
.Class_Data_Setup = usbDataSetup,
|
||||
.Class_NoData_Setup = usbNoDataSetup,
|
||||
.Class_Get_Interface_Setting = usbGetInterfaceSetting,
|
||||
.GetDeviceDescriptor = usbGetDeviceDescriptor,
|
||||
.GetConfigDescriptor = usbGetConfigDescriptor,
|
||||
.GetStringDescriptor = usbGetStringDescriptor,
|
||||
.RxEP_buffer = NULL,
|
||||
.MaxPacketSize = MAX_PACKET_SIZE
|
||||
};
|
||||
|
||||
__weak USER_STANDARD_REQUESTS User_Standard_Requests = {
|
||||
.User_GetConfiguration = NOP_Process,
|
||||
.User_SetConfiguration = usbSetConfiguration,
|
||||
.User_GetInterface = NOP_Process,
|
||||
.User_SetInterface = NOP_Process,
|
||||
.User_GetStatus = NOP_Process,
|
||||
.User_ClearFeature = NOP_Process,
|
||||
.User_SetEndPointFeature = NOP_Process,
|
||||
.User_SetDeviceFeature = NOP_Process,
|
||||
.User_SetDeviceAddress = usbSetDeviceAddress
|
||||
};
|
||||
|
||||
/*
|
||||
* User hooks
|
||||
*/
|
||||
|
||||
static void (*rx_hook)(unsigned, void*) = 0;
|
||||
static void (*iface_setup_hook)(unsigned, void*) = 0;
|
||||
|
||||
void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)) {
|
||||
if (hook_flags & USB_CDCACM_HOOK_RX) {
|
||||
rx_hook = hook;
|
||||
}
|
||||
if (hook_flags & USB_CDCACM_HOOK_IFACE_SETUP) {
|
||||
iface_setup_hook = hook;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CDC ACM interface
|
||||
*/
|
||||
|
||||
void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) {
|
||||
/* Present ourselves to the host. Writing 0 to "disc" pin must
|
||||
* pull USB_DP pin up while leaving USB_DM pulled down by the
|
||||
* transceiver. See USB 2.0 spec, section 7.1.7.3. */
|
||||
|
||||
if (disc_dev!=NULL)
|
||||
{
|
||||
gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP);
|
||||
gpio_write_bit(disc_dev, disc_bit, 0);
|
||||
}
|
||||
|
||||
/* Initialize the USB peripheral. */
|
||||
usb_init_usblib(USBLIB, ep_int_in, ep_int_out);
|
||||
}
|
||||
|
||||
void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) {
|
||||
/* Turn off the interrupt and signal disconnect (see e.g. USB 2.0
|
||||
* spec, section 7.1.7.3). */
|
||||
nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
|
||||
if (disc_dev!=NULL)
|
||||
{
|
||||
gpio_write_bit(disc_dev, disc_bit, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_cdcacm_putc(char ch) {
|
||||
while (!usb_cdcacm_tx((uint8*)&ch, 1))
|
||||
;
|
||||
}
|
||||
|
||||
/* This function is non-blocking.
|
||||
*
|
||||
* It copies data from a user buffer into the USB peripheral TX
|
||||
* buffer, and returns the number of bytes copied. */
|
||||
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len)
|
||||
{
|
||||
if (len==0) return 0; // no data to send
|
||||
|
||||
uint32 head = tx_head; // load volatile variable
|
||||
uint32 tx_unsent = (head - tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK;
|
||||
|
||||
// We can only put bytes in the buffer if there is place
|
||||
if (len > (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1) ) {
|
||||
len = (CDC_SERIAL_TX_BUFFER_SIZE-tx_unsent-1);
|
||||
}
|
||||
if (len==0) return 0; // buffer full
|
||||
|
||||
uint16 i;
|
||||
// copy data from user buffer to USB Tx buffer
|
||||
for (i=0; i<len; i++) {
|
||||
vcomBufferTx[head] = buf[i];
|
||||
head = (head+1) & CDC_SERIAL_TX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
tx_head = head; // store volatile variable
|
||||
|
||||
if (transmitting<0) {
|
||||
vcomDataTxCb(); // initiate data transmission
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32 usb_cdcacm_data_available(void) {
|
||||
return (rx_head - rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
|
||||
uint8 usb_cdcacm_is_transmitting(void) {
|
||||
return ( transmitting>0 ? transmitting : 0);
|
||||
}
|
||||
|
||||
uint16 usb_cdcacm_get_pending(void) {
|
||||
return (tx_head - tx_tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
|
||||
/* Non-blocking byte receive.
|
||||
*
|
||||
* Copies up to len bytes from our private data buffer (*NOT* the PMA)
|
||||
* into buf and deq's the FIFO. */
|
||||
uint32 usb_cdcacm_rx(uint8* buf, uint32 len)
|
||||
{
|
||||
/* Copy bytes to buffer. */
|
||||
uint32 n_copied = usb_cdcacm_peek(buf, len);
|
||||
|
||||
/* Mark bytes as read. */
|
||||
uint16 tail = rx_tail; // load volatile variable
|
||||
tail = (tail + n_copied) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
rx_tail = tail; // store volatile variable
|
||||
|
||||
uint32 rx_unread = (rx_head - tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
// If buffer was emptied to a pre-set value, re-enable the RX endpoint
|
||||
if ( rx_unread <= 64 ) { // experimental value, gives the best performance
|
||||
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
|
||||
}
|
||||
return n_copied;
|
||||
}
|
||||
|
||||
/* Non-blocking byte lookahead.
|
||||
*
|
||||
* Looks at unread bytes without marking them as read. */
|
||||
uint32 usb_cdcacm_peek(uint8* buf, uint32 len)
|
||||
{
|
||||
int i;
|
||||
uint32 tail = rx_tail;
|
||||
uint32 rx_unread = (rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
|
||||
if (len > rx_unread) {
|
||||
len = rx_unread;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i] = vcomBufferRx[tail];
|
||||
tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len)
|
||||
{
|
||||
int i;
|
||||
uint32 tail = (rx_tail + offset) & CDC_SERIAL_RX_BUFFER_SIZE_MASK ;
|
||||
uint32 rx_unread = (rx_head-tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
|
||||
if (len + offset > rx_unread) {
|
||||
len = rx_unread - offset;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
buf[i] = vcomBufferRx[tail];
|
||||
tail = (tail + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Roger Clark. Added. for Arduino 1.0 API support of Serial.peek() */
|
||||
int usb_cdcacm_peek_char()
|
||||
{
|
||||
if (usb_cdcacm_data_available() == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vcomBufferRx[rx_tail];
|
||||
}
|
||||
|
||||
uint8 usb_cdcacm_get_dtr() {
|
||||
return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_DTR) != 0);
|
||||
}
|
||||
|
||||
uint8 usb_cdcacm_get_rts() {
|
||||
return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_RTS) != 0);
|
||||
}
|
||||
|
||||
void usb_cdcacm_get_line_coding(usb_cdcacm_line_coding *ret) {
|
||||
ret->dwDTERate = line_coding.dwDTERate;
|
||||
ret->bCharFormat = line_coding.bCharFormat;
|
||||
ret->bParityType = line_coding.bParityType;
|
||||
ret->bDataBits = line_coding.bDataBits;
|
||||
}
|
||||
|
||||
int usb_cdcacm_get_baud(void) {
|
||||
return line_coding.dwDTERate;
|
||||
}
|
||||
|
||||
int usb_cdcacm_get_stop_bits(void) {
|
||||
return line_coding.bCharFormat;
|
||||
}
|
||||
|
||||
int usb_cdcacm_get_parity(void) {
|
||||
return line_coding.bParityType;
|
||||
}
|
||||
|
||||
int usb_cdcacm_get_n_data_bits(void) {
|
||||
return line_coding.bDataBits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callbacks
|
||||
*/
|
||||
static void vcomDataTxCb(void)
|
||||
{
|
||||
uint32 tail = tx_tail; // load volatile variable
|
||||
uint32 tx_unsent = (tx_head - tail) & CDC_SERIAL_TX_BUFFER_SIZE_MASK;
|
||||
if (tx_unsent==0) {
|
||||
if ( (--transmitting)==0) goto flush; // no more data to send
|
||||
return; // it was already flushed, keep Tx endpoint disabled
|
||||
}
|
||||
transmitting = 1;
|
||||
// We can only send up to USB_CDCACM_TX_EPSIZE bytes in the endpoint.
|
||||
if (tx_unsent > USB_CDCACM_TX_EPSIZE) {
|
||||
tx_unsent = USB_CDCACM_TX_EPSIZE;
|
||||
}
|
||||
// copy the bytes from USB Tx buffer to PMA buffer
|
||||
uint32 *dst = usb_pma_ptr(USB_CDCACM_TX_ADDR);
|
||||
uint16 tmp = 0;
|
||||
uint16 val;
|
||||
int i;
|
||||
for (i = 0; i < tx_unsent; i++) {
|
||||
val = vcomBufferTx[tail];
|
||||
tail = (tail + 1) & CDC_SERIAL_TX_BUFFER_SIZE_MASK;
|
||||
if (i&1) {
|
||||
*dst++ = tmp | (val<<8);
|
||||
} else {
|
||||
tmp = val;
|
||||
}
|
||||
}
|
||||
if ( tx_unsent&1 ) {
|
||||
*dst = tmp;
|
||||
}
|
||||
tx_tail = tail; // store volatile variable
|
||||
flush:
|
||||
// enable Tx endpoint
|
||||
usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, tx_unsent);
|
||||
usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID);
|
||||
}
|
||||
|
||||
|
||||
static void vcomDataRxCb(void)
|
||||
{
|
||||
uint32 head = rx_head; // load volatile variable
|
||||
|
||||
uint32 ep_rx_size = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP);
|
||||
// This copy won't overwrite unread bytes as long as there is
|
||||
// enough room in the USB Rx buffer for next packet
|
||||
uint32 *src = usb_pma_ptr(USB_CDCACM_RX_ADDR);
|
||||
uint16 tmp = 0;
|
||||
uint8 val;
|
||||
uint32 i;
|
||||
for (i = 0; i < ep_rx_size; i++) {
|
||||
if (i&1) {
|
||||
val = tmp>>8;
|
||||
} else {
|
||||
tmp = *src++;
|
||||
val = tmp&0xFF;
|
||||
}
|
||||
vcomBufferRx[head] = val;
|
||||
head = (head + 1) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
}
|
||||
rx_head = head; // store volatile variable
|
||||
|
||||
uint32 rx_unread = (head - rx_tail) & CDC_SERIAL_RX_BUFFER_SIZE_MASK;
|
||||
// only enable further Rx if there is enough room to receive one more packet
|
||||
if ( rx_unread < (CDC_SERIAL_RX_BUFFER_SIZE-USB_CDCACM_RX_EPSIZE) ) {
|
||||
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
|
||||
}
|
||||
|
||||
if (rx_hook) {
|
||||
rx_hook(USB_CDCACM_HOOK_RX, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8* vcomGetSetLineCoding(uint16 length) {
|
||||
if (length == 0) {
|
||||
pInformation->Ctrl_Info.Usb_wLength = sizeof(struct usb_cdcacm_line_coding);
|
||||
}
|
||||
return (uint8*)&line_coding;
|
||||
}
|
||||
|
||||
static void usbInit(void) {
|
||||
pInformation->Current_Configuration = 0;
|
||||
|
||||
USB_BASE->CNTR = USB_CNTR_FRES;
|
||||
|
||||
USBLIB->irq_mask = 0;
|
||||
USB_BASE->CNTR = USBLIB->irq_mask;
|
||||
USB_BASE->ISTR = 0;
|
||||
USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
|
||||
USB_BASE->CNTR = USBLIB->irq_mask;
|
||||
|
||||
USB_BASE->ISTR = 0;
|
||||
USBLIB->irq_mask = USB_ISR_MSK;
|
||||
USB_BASE->CNTR = USBLIB->irq_mask;
|
||||
|
||||
nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
|
||||
USBLIB->state = USB_UNCONNECTED;
|
||||
}
|
||||
|
||||
#define BTABLE_ADDRESS 0x00
|
||||
static void usbReset(void) {
|
||||
pInformation->Current_Configuration = 0;
|
||||
|
||||
/* current feature is current bmAttributes */
|
||||
pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED |
|
||||
USB_CONFIG_ATTR_SELF_POWERED);
|
||||
|
||||
USB_BASE->BTABLE = BTABLE_ADDRESS;
|
||||
|
||||
/* setup control endpoint 0 */
|
||||
usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL);
|
||||
usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL);
|
||||
usb_set_ep_rx_addr(USB_EP0, USB_CDCACM_CTRL_RX_ADDR);
|
||||
usb_set_ep_tx_addr(USB_EP0, USB_CDCACM_CTRL_TX_ADDR);
|
||||
usb_clear_status_out(USB_EP0);
|
||||
|
||||
usb_set_ep_rx_count(USB_EP0, pProperty->MaxPacketSize);
|
||||
usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID);
|
||||
|
||||
/* setup management endpoint 1 */
|
||||
usb_set_ep_type(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_EP_TYPE_INTERRUPT);
|
||||
usb_set_ep_tx_addr(USB_CDCACM_MANAGEMENT_ENDP,
|
||||
USB_CDCACM_MANAGEMENT_ADDR);
|
||||
usb_set_ep_tx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_TX_NAK);
|
||||
usb_set_ep_rx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_RX_DISABLED);
|
||||
|
||||
/* TODO figure out differences in style between RX/TX EP setup */
|
||||
|
||||
/* set up data endpoint OUT (RX) */
|
||||
usb_set_ep_type(USB_CDCACM_RX_ENDP, USB_EP_EP_TYPE_BULK);
|
||||
usb_set_ep_rx_addr(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_ADDR);
|
||||
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
|
||||
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
|
||||
|
||||
/* set up data endpoint IN (TX) */
|
||||
usb_set_ep_type(USB_CDCACM_TX_ENDP, USB_EP_EP_TYPE_BULK);
|
||||
usb_set_ep_tx_addr(USB_CDCACM_TX_ENDP, USB_CDCACM_TX_ADDR);
|
||||
usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_NAK);
|
||||
usb_set_ep_rx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_RX_DISABLED);
|
||||
|
||||
USBLIB->state = USB_ATTACHED;
|
||||
SetDeviceAddress(0);
|
||||
|
||||
/* Reset the RX/TX state */
|
||||
rx_head = 0;
|
||||
rx_tail = 0;
|
||||
tx_head = 0;
|
||||
tx_tail = 0;
|
||||
transmitting = -1;
|
||||
}
|
||||
|
||||
static RESULT usbDataSetup(uint8 request) {
|
||||
uint8* (*CopyRoutine)(uint16) = 0;
|
||||
|
||||
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
|
||||
switch (request) {
|
||||
case USB_CDCACM_GET_LINE_CODING:
|
||||
CopyRoutine = vcomGetSetLineCoding;
|
||||
break;
|
||||
case USB_CDCACM_SET_LINE_CODING:
|
||||
CopyRoutine = vcomGetSetLineCoding;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Call the user hook. */
|
||||
if (iface_setup_hook) {
|
||||
uint8 req_copy = request;
|
||||
iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy);
|
||||
}
|
||||
}
|
||||
|
||||
if (CopyRoutine == NULL) {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
pInformation->Ctrl_Info.CopyData = CopyRoutine;
|
||||
pInformation->Ctrl_Info.Usb_wOffset = 0;
|
||||
(*CopyRoutine)(0);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
static RESULT usbNoDataSetup(uint8 request) {
|
||||
RESULT ret = USB_UNSUPPORT;
|
||||
|
||||
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
|
||||
switch (request) {
|
||||
case USB_CDCACM_SET_COMM_FEATURE:
|
||||
/* We support set comm. feature, but don't handle it. */
|
||||
ret = USB_SUCCESS;
|
||||
break;
|
||||
case USB_CDCACM_SET_CONTROL_LINE_STATE:
|
||||
/* Track changes to DTR and RTS. */
|
||||
line_dtr_rts = (pInformation->USBwValues.bw.bb0 &
|
||||
(USB_CDCACM_CONTROL_LINE_DTR |
|
||||
USB_CDCACM_CONTROL_LINE_RTS));
|
||||
ret = USB_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Call the user hook. */
|
||||
if (iface_setup_hook) {
|
||||
uint8 req_copy = request;
|
||||
iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) {
|
||||
if (alt_setting > 0) {
|
||||
return USB_UNSUPPORT;
|
||||
} else if (interface > 1) {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8* usbGetDeviceDescriptor(uint16 length) {
|
||||
return Standard_GetDescriptorData(length, &Device_Descriptor);
|
||||
}
|
||||
|
||||
static uint8* usbGetConfigDescriptor(uint16 length) {
|
||||
return Standard_GetDescriptorData(length, &Config_Descriptor);
|
||||
}
|
||||
|
||||
static uint8* usbGetStringDescriptor(uint16 length) {
|
||||
uint8 wValue0 = pInformation->USBwValue0;
|
||||
|
||||
if (wValue0 > N_STRING_DESCRIPTORS) {
|
||||
return NULL;
|
||||
}
|
||||
return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]);
|
||||
}
|
||||
|
||||
static void usbSetConfiguration(void) {
|
||||
if (pInformation->Current_Configuration != 0) {
|
||||
USBLIB->state = USB_CONFIGURED;
|
||||
}
|
||||
}
|
||||
|
||||
static void usbSetDeviceAddress(void) {
|
||||
USBLIB->state = USB_ADDRESSED;
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "usb_reg_map.h"
|
||||
|
||||
/* TODO these could use some improvement; they're fairly
|
||||
* straightforward ports of the analogous ST code. The PMA blit
|
||||
* routines in particular are obvious targets for performance
|
||||
* measurement and tuning.
|
||||
|
||||
void usb_copy_to_pma(const uint8 *buf, uint16 len, uint16 pma_offset) {
|
||||
uint16 *dst = (uint16*)usb_pma_ptr(pma_offset);
|
||||
uint16 n = len >> 1;
|
||||
uint16 i;
|
||||
for (i = 0; i < n; i++) {
|
||||
*dst = (uint16)(*buf) | *(buf + 1) << 8;
|
||||
buf += 2;
|
||||
dst += 2;
|
||||
}
|
||||
if (len & 1) {
|
||||
*dst = *buf;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_copy_from_pma(uint8 *buf, uint16 len, uint16 pma_offset) {
|
||||
uint32 *src = (uint32*)usb_pma_ptr(pma_offset);
|
||||
uint16 *dst = (uint16*)buf;
|
||||
uint16 n = len >> 1;
|
||||
uint16 i;
|
||||
for (i = 0; i < n; i++) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
if (len & 1) {
|
||||
*dst = *src & 0xFF;
|
||||
}
|
||||
}
|
||||
*/
|
||||
static void usb_set_ep_rx_count_common(uint32 *rxc, uint16 count) {
|
||||
uint16 nblocks;
|
||||
if (count > 62) {
|
||||
/* use 32-byte memory block size */
|
||||
nblocks = count >> 5;
|
||||
if ((count & 0x1F) == 0) {
|
||||
nblocks--;
|
||||
}
|
||||
*rxc = (nblocks << 10) | 0x8000;
|
||||
} else {
|
||||
/* use 2-byte memory block size */
|
||||
nblocks = count >> 1;
|
||||
if ((count & 0x1) != 0) {
|
||||
nblocks++;
|
||||
}
|
||||
*rxc = nblocks << 10;
|
||||
}
|
||||
}
|
||||
/*
|
||||
void usb_set_ep_rx_buf0_count(uint8 ep, uint16 count) {
|
||||
uint32 *rxc = usb_ep_rx_buf0_count_ptr(ep);
|
||||
usb_set_ep_rx_count_common(rxc, count);
|
||||
}
|
||||
*/
|
||||
void usb_set_ep_rx_count(uint8 ep, uint16 count) {
|
||||
uint32 *rxc = usb_ep_rx_count_ptr(ep);
|
||||
usb_set_ep_rx_count_common(rxc, count);
|
||||
}
|
1010
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/usb_lib/usb_core.c
Normal file
1010
BootLoaders/Boards/stm32/cores/maple/libmaple/usb/usb_lib/usb_core.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
|
||||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||
* File Name : usb_init.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V2.2.1
|
||||
* Date : 09/22/2008
|
||||
* Description : Initialization routines & global variables
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usb_lib.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* The number of current endpoint, it will be used to specify an endpoint */
|
||||
u8 EPindex;
|
||||
/* The number of current device, it is an index to the Device_Table */
|
||||
/* u8 Device_no; */
|
||||
/* Points to the DEVICE_INFO structure of current device */
|
||||
/* The purpose of this register is to speed up the execution */
|
||||
DEVICE_INFO *pInformation;
|
||||
/* Points to the DEVICE_PROP structure of current device */
|
||||
/* The purpose of this register is to speed up the execution */
|
||||
DEVICE_PROP *pProperty;
|
||||
/* Temporary save the state of Rx & Tx status. */
|
||||
/* Whenever the Rx or Tx state is changed, its value is saved */
|
||||
/* in this variable first and will be set to the EPRB or EPRA */
|
||||
/* at the end of interrupt process */
|
||||
u16 SaveState ;
|
||||
u16 wInterrupt_Mask;
|
||||
DEVICE_INFO Device_Info;
|
||||
USER_STANDARD_REQUESTS *pUser_Standard_Requests;
|
||||
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USB_Init
|
||||
* Description : USB system initialization
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void USB_Init(void)
|
||||
{
|
||||
pInformation = &Device_Info;
|
||||
pInformation->ControlState = 2;
|
||||
pProperty = &Device_Property;
|
||||
pUser_Standard_Requests = &User_Standard_Requests;
|
||||
/* Initialize devices one by one */
|
||||
|
||||
pProperty->Init();
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,73 @@
|
||||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||
* File Name : usb_mem.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V2.2.1
|
||||
* Date : 09/22/2008
|
||||
* Description : Utility functions for memory transfers to/from PMA
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usb_lib.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/*******************************************************************************
|
||||
* Function Name : UserToPMABufferCopy
|
||||
* Description : Copy a buffer from user memory area to packet memory area (PMA)
|
||||
* Input : - pbUsrBuf: pointer to user memory area.
|
||||
* - wPMABufAddr: address into PMA.
|
||||
* - wNBytes: no. of bytes to be copied.
|
||||
* Output : None.
|
||||
* Return : None .
|
||||
*******************************************************************************/
|
||||
void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes)
|
||||
{
|
||||
u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */
|
||||
u32 i, temp1, temp2;
|
||||
u16 *pdwVal;
|
||||
pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr);
|
||||
for (i = n; i != 0; i--)
|
||||
{
|
||||
temp1 = (u16) * pbUsrBuf;
|
||||
pbUsrBuf++;
|
||||
temp2 = temp1 | (u16) * pbUsrBuf << 8;
|
||||
*pdwVal++ = temp2;
|
||||
pdwVal++;
|
||||
pbUsrBuf++;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : PMAToUserBufferCopy
|
||||
* Description : Copy a buffer from user memory area to packet memory area (PMA)
|
||||
* Input : - pbUsrBuf = pointer to user memory area.
|
||||
* - wPMABufAddr = address into PMA.
|
||||
* - wNBytes = no. of bytes to be copied.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes)
|
||||
{
|
||||
u32 n = (wNBytes + 1) >> 1;/* /2*/
|
||||
u32 i;
|
||||
u32 *pdwVal;
|
||||
pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr);
|
||||
for (i = n; i != 0; i--)
|
||||
{
|
||||
*(u16*)pbUsrBuf++ = *pdwVal++;
|
||||
pbUsrBuf++;
|
||||
}
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,748 @@
|
||||
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
||||
* File Name : usb_regs.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V2.2.1
|
||||
* Date : 09/22/2008
|
||||
* Description : Interface functions to USB cell registers
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usb_lib.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetCNTR.
|
||||
* Description : Set the CNTR register value.
|
||||
* Input : wRegValue: new register value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetCNTR(u16 wRegValue)
|
||||
{
|
||||
_SetCNTR(wRegValue);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetCNTR.
|
||||
* Description : returns the CNTR register value.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : CNTR register Value.
|
||||
*******************************************************************************/
|
||||
u16 GetCNTR(void)
|
||||
{
|
||||
return(_GetCNTR());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetISTR.
|
||||
* Description : Set the ISTR register value.
|
||||
* Input : wRegValue: new register value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetISTR(u16 wRegValue)
|
||||
{
|
||||
_SetISTR(wRegValue);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetISTR
|
||||
* Description : Returns the ISTR register value.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : ISTR register Value
|
||||
*******************************************************************************/
|
||||
u16 GetISTR(void)
|
||||
{
|
||||
return(_GetISTR());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetFNR
|
||||
* Description : Returns the FNR register value.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : FNR register Value
|
||||
*******************************************************************************/
|
||||
u16 GetFNR(void)
|
||||
{
|
||||
return(_GetFNR());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetDADDR
|
||||
* Description : Set the DADDR register value.
|
||||
* Input : wRegValue: new register value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetDADDR(u16 wRegValue)
|
||||
{
|
||||
_SetDADDR(wRegValue);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetDADDR
|
||||
* Description : Returns the DADDR register value.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : DADDR register Value
|
||||
*******************************************************************************/
|
||||
u16 GetDADDR(void)
|
||||
{
|
||||
return(_GetDADDR());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetBTABLE
|
||||
* Description : Set the BTABLE.
|
||||
* Input : wRegValue: New register value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetBTABLE(u16 wRegValue)
|
||||
{
|
||||
_SetBTABLE(wRegValue);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetBTABLE.
|
||||
* Description : Returns the BTABLE register value.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : BTABLE address.
|
||||
*******************************************************************************/
|
||||
u16 GetBTABLE(void)
|
||||
{
|
||||
return(_GetBTABLE());
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetENDPOINT
|
||||
* Description : Setthe Endpoint register value.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wRegValue.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetENDPOINT(u8 bEpNum, u16 wRegValue)
|
||||
{
|
||||
_SetENDPOINT(bEpNum, wRegValue);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetENDPOINT
|
||||
* Description : Return the Endpoint register value.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint register value.
|
||||
*******************************************************************************/
|
||||
u16 GetENDPOINT(u8 bEpNum)
|
||||
{
|
||||
return(_GetENDPOINT(bEpNum));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPType
|
||||
* Description : sets the type in the endpoint register.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wType: type definition.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPType(u8 bEpNum, u16 wType)
|
||||
{
|
||||
_SetEPType(bEpNum, wType);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPType
|
||||
* Description : Returns the endpoint type.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint Type
|
||||
*******************************************************************************/
|
||||
u16 GetEPType(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPType(bEpNum));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPTxStatus
|
||||
* Description : Set the status of Tx endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wState: new state.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPTxStatus(u8 bEpNum, u16 wState)
|
||||
{
|
||||
_SetEPTxStatus(bEpNum, wState);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPRxStatus
|
||||
* Description : Set the status of Rx endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wState: new state.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPRxStatus(u8 bEpNum, u16 wState)
|
||||
{
|
||||
_SetEPRxStatus(bEpNum, wState);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetDouBleBuffEPStall
|
||||
* Description : sets the status for Double Buffer Endpoint to STALL
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* bDir: Endpoint direction.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir)
|
||||
{
|
||||
u16 Endpoint_DTOG_Status;
|
||||
Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
|
||||
if (bDir == EP_DBUF_OUT)
|
||||
{ /* OUT double buffered endpoint */
|
||||
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
|
||||
}
|
||||
else if (bDir == EP_DBUF_IN)
|
||||
{ /* IN double buffered endpoint */
|
||||
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPTxStatus
|
||||
* Description : Returns the endpoint Tx status.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint TX Status
|
||||
*******************************************************************************/
|
||||
u16 GetEPTxStatus(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPTxStatus(bEpNum));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPRxStatus
|
||||
* Description : Returns the endpoint Rx status.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint RX Status
|
||||
*******************************************************************************/
|
||||
u16 GetEPRxStatus(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPRxStatus(bEpNum));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPTxValid
|
||||
* Description : Valid the endpoint Tx Status.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPTxValid(u8 bEpNum)
|
||||
{
|
||||
_SetEPTxStatus(bEpNum, EP_TX_VALID);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPRxValid
|
||||
* Description : Valid the endpoint Rx Status.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPRxValid(u8 bEpNum)
|
||||
{
|
||||
_SetEPRxStatus(bEpNum, EP_RX_VALID);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEP_KIND
|
||||
* Description : Clear the EP_KIND bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEP_KIND(u8 bEpNum)
|
||||
{
|
||||
_SetEP_KIND(bEpNum);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearEP_KIND
|
||||
* Description : set the EP_KIND bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearEP_KIND(u8 bEpNum)
|
||||
{
|
||||
_ClearEP_KIND(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : Clear_Status_Out
|
||||
* Description : Clear the Status Out of the related Endpoint
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void Clear_Status_Out(u8 bEpNum)
|
||||
{
|
||||
_ClearEP_KIND(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : Set_Status_Out
|
||||
* Description : Set the Status Out of the related Endpoint
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void Set_Status_Out(u8 bEpNum)
|
||||
{
|
||||
_SetEP_KIND(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDoubleBuff
|
||||
* Description : Enable the double buffer feature for the endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDoubleBuff(u8 bEpNum)
|
||||
{
|
||||
_SetEP_KIND(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearEPDoubleBuff
|
||||
* Description : Disable the double buffer feature for the endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearEPDoubleBuff(u8 bEpNum)
|
||||
{
|
||||
_ClearEP_KIND(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetTxStallStatus
|
||||
* Description : Returns the Stall status of the Tx endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Tx Stall status.
|
||||
*******************************************************************************/
|
||||
u16 GetTxStallStatus(u8 bEpNum)
|
||||
{
|
||||
return(_GetTxStallStatus(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetRxStallStatus
|
||||
* Description : Returns the Stall status of the Rx endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Rx Stall status.
|
||||
*******************************************************************************/
|
||||
u16 GetRxStallStatus(u8 bEpNum)
|
||||
{
|
||||
return(_GetRxStallStatus(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearEP_CTR_RX
|
||||
* Description : Clear the CTR_RX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearEP_CTR_RX(u8 bEpNum)
|
||||
{
|
||||
_ClearEP_CTR_RX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearEP_CTR_TX
|
||||
* Description : Clear the CTR_TX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearEP_CTR_TX(u8 bEpNum)
|
||||
{
|
||||
_ClearEP_CTR_TX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ToggleDTOG_RX
|
||||
* Description : Toggle the DTOG_RX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ToggleDTOG_RX(u8 bEpNum)
|
||||
{
|
||||
_ToggleDTOG_RX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ToggleDTOG_TX
|
||||
* Description : Toggle the DTOG_TX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ToggleDTOG_TX(u8 bEpNum)
|
||||
{
|
||||
_ToggleDTOG_TX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearDTOG_RX.
|
||||
* Description : Clear the DTOG_RX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearDTOG_RX(u8 bEpNum)
|
||||
{
|
||||
_ClearDTOG_RX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ClearDTOG_TX.
|
||||
* Description : Clear the DTOG_TX bit.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void ClearDTOG_TX(u8 bEpNum)
|
||||
{
|
||||
_ClearDTOG_TX(bEpNum);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPAddress
|
||||
* Description : Set the endpoint address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* bAddr: New endpoint address.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPAddress(u8 bEpNum, u8 bAddr)
|
||||
{
|
||||
_SetEPAddress(bEpNum, bAddr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPAddress
|
||||
* Description : Get the endpoint address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint address.
|
||||
*******************************************************************************/
|
||||
u8 GetEPAddress(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPAddress(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPTxAddr
|
||||
* Description : Set the endpoint Tx buffer address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wAddr: new address.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPTxAddr(u8 bEpNum, u16 wAddr)
|
||||
{
|
||||
_SetEPTxAddr(bEpNum, wAddr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPRxAddr
|
||||
* Description : Set the endpoint Rx buffer address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wAddr: new address.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPRxAddr(u8 bEpNum, u16 wAddr)
|
||||
{
|
||||
_SetEPRxAddr(bEpNum, wAddr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPTxAddr
|
||||
* Description : Returns the endpoint Tx buffer address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Rx buffer address.
|
||||
*******************************************************************************/
|
||||
u16 GetEPTxAddr(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPTxAddr(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPRxAddr.
|
||||
* Description : Returns the endpoint Rx buffer address.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Rx buffer address.
|
||||
*******************************************************************************/
|
||||
u16 GetEPRxAddr(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPRxAddr(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPTxCount.
|
||||
* Description : Set the Tx count.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wCount: new count value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPTxCount(u8 bEpNum, u16 wCount)
|
||||
{
|
||||
_SetEPTxCount(bEpNum, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPCountRxReg.
|
||||
* Description : Set the Count Rx Register value.
|
||||
* Input : *pdwReg: point to the register.
|
||||
* wCount: the new register value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPCountRxReg(u32 *pdwReg, u16 wCount)
|
||||
{
|
||||
_SetEPCountRxReg(dwReg, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPRxCount
|
||||
* Description : Set the Rx count.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wCount: the new count value.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPRxCount(u8 bEpNum, u16 wCount)
|
||||
{
|
||||
_SetEPRxCount(bEpNum, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPTxCount
|
||||
* Description : Get the Tx count.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None
|
||||
* Return : Tx count value.
|
||||
*******************************************************************************/
|
||||
u16 GetEPTxCount(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPTxCount(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPRxCount
|
||||
* Description : Get the Rx count.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Rx count value.
|
||||
*******************************************************************************/
|
||||
u16 GetEPRxCount(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPRxCount(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuffAddr
|
||||
* Description : Set the addresses of the buffer 0 and 1.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* wBuf0Addr: new address of buffer 0.
|
||||
* wBuf1Addr: new address of buffer 1.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr)
|
||||
{
|
||||
_SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuf0Addr
|
||||
* Description : Set the Buffer 1 address.
|
||||
* Input : bEpNum: Endpoint Number
|
||||
* wBuf0Addr: new address.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr)
|
||||
{
|
||||
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuf1Addr
|
||||
* Description : Set the Buffer 1 address.
|
||||
* Input : bEpNum: Endpoint Number
|
||||
* wBuf1Addr: new address.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr)
|
||||
{
|
||||
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPDblBuf0Addr
|
||||
* Description : Returns the address of the Buffer 0.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
u16 GetEPDblBuf0Addr(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPDblBuf0Addr(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPDblBuf1Addr
|
||||
* Description : Returns the address of the Buffer 1.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Address of the Buffer 1.
|
||||
*******************************************************************************/
|
||||
u16 GetEPDblBuf1Addr(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPDblBuf1Addr(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuffCount
|
||||
* Description : Set the number of bytes for a double Buffer
|
||||
* endpoint.
|
||||
* Input : bEpNum,bDir, wCount
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount)
|
||||
{
|
||||
_SetEPDblBuffCount(bEpNum, bDir, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuf0Count
|
||||
* Description : Set the number of bytes in the buffer 0 of a double Buffer
|
||||
* endpoint.
|
||||
* Input : bEpNum, bDir, wCount
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount)
|
||||
{
|
||||
_SetEPDblBuf0Count(bEpNum, bDir, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : SetEPDblBuf1Count
|
||||
* Description : Set the number of bytes in the buffer 0 of a double Buffer
|
||||
* endpoint.
|
||||
* Input : bEpNum, bDir, wCount
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount)
|
||||
{
|
||||
_SetEPDblBuf1Count(bEpNum, bDir, wCount);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPDblBuf0Count
|
||||
* Description : Returns the number of byte received in the buffer 0 of a double
|
||||
* Buffer endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint Buffer 0 count
|
||||
*******************************************************************************/
|
||||
u16 GetEPDblBuf0Count(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPDblBuf0Count(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPDblBuf1Count
|
||||
* Description : Returns the number of data received in the buffer 1 of a double
|
||||
* Buffer endpoint.
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : Endpoint Buffer 1 count.
|
||||
*******************************************************************************/
|
||||
u16 GetEPDblBuf1Count(u8 bEpNum)
|
||||
{
|
||||
return(_GetEPDblBuf1Count(bEpNum));
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : GetEPDblBufDir
|
||||
* Description : gets direction of the double buffered endpoint
|
||||
* Input : bEpNum: Endpoint Number.
|
||||
* Output : None.
|
||||
* Return : EP_DBUF_OUT, EP_DBUF_IN,
|
||||
* EP_DBUF_ERR if the endpoint counter not yet programmed.
|
||||
*******************************************************************************/
|
||||
EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum)
|
||||
{
|
||||
if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
|
||||
return(EP_DBUF_OUT);
|
||||
else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
|
||||
return(EP_DBUF_IN);
|
||||
else
|
||||
return(EP_DBUF_ERR);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : FreeUserBuffer
|
||||
* Description : free buffer used from the application realizing it to the line
|
||||
toggles bit SW_BUF in the double buffered endpoint register
|
||||
* Input : bEpNum, bDir
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void FreeUserBuffer(u8 bEpNum, u8 bDir)
|
||||
{
|
||||
if (bDir == EP_DBUF_OUT)
|
||||
{ /* OUT double buffered endpoint */
|
||||
_ToggleDTOG_TX(bEpNum);
|
||||
}
|
||||
else if (bDir == EP_DBUF_IN)
|
||||
{ /* IN double buffered endpoint */
|
||||
_ToggleDTOG_RX(bEpNum);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ToWord
|
||||
* Description : merge two byte in a word.
|
||||
* Input : bh: byte high, bl: bytes low.
|
||||
* Output : None.
|
||||
* Return : resulted word.
|
||||
*******************************************************************************/
|
||||
u16 ToWord(u8 bh, u8 bl)
|
||||
{
|
||||
u16 wRet;
|
||||
wRet = (u16)bl | ((u16)bh << 8);
|
||||
return(wRet);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : ByteSwap
|
||||
* Description : Swap two byte in a word.
|
||||
* Input : wSwW: word to Swap.
|
||||
* Output : None.
|
||||
* Return : resulted word.
|
||||
*******************************************************************************/
|
||||
u16 ByteSwap(u16 wSwW)
|
||||
{
|
||||
u8 bTemp;
|
||||
u16 wRet;
|
||||
bTemp = (u8)(wSwW & 0xff);
|
||||
wRet = (wSwW >> 8) | ((u16)bTemp << 8);
|
||||
return(wRet);
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
|
150
BootLoaders/Boards/stm32/cores/maple/libmaple/util.c
Normal file
150
BootLoaders/Boards/stm32/cores/maple/libmaple/util.c
Normal file
@ -0,0 +1,150 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/util.c
|
||||
* @brief Utility procedures for debugging
|
||||
*/
|
||||
|
||||
#include <libmaple/libmaple.h>
|
||||
#include <libmaple/usart.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/nvic.h>
|
||||
|
||||
/* (Undocumented) hooks used by Wirish to direct our behavior here */
|
||||
extern __weak void __lm_error(void);
|
||||
extern __weak usart_dev* __lm_enable_error_usart(void);
|
||||
|
||||
/* If you define ERROR_LED_PORT and ERROR_LED_PIN, then a failed
|
||||
* ASSERT() will also throb() an LED connected to that port and pin.
|
||||
*/
|
||||
#if defined(ERROR_LED_PORT) && defined(ERROR_LED_PIN)
|
||||
#define HAVE_ERROR_LED
|
||||
#endif
|
||||
|
||||
/* (Called from exc.S with global interrupts disabled.) */
|
||||
__attribute__((noreturn)) void __error(void) {
|
||||
if (__lm_error) {
|
||||
__lm_error();
|
||||
}
|
||||
/* Reenable global interrupts */
|
||||
nvic_globalirq_enable();
|
||||
throb();
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an error message on a UART upon a failed assertion (if one is
|
||||
* available), and punt to __error().
|
||||
*
|
||||
* @param file Source file of failed assertion
|
||||
* @param line Source line of failed assertion
|
||||
* @param exp String representation of failed assertion
|
||||
* @sideeffect Turns of all peripheral interrupts except USB.
|
||||
*/
|
||||
void _fail(const char* file, int line, const char* exp) {
|
||||
if (__lm_enable_error_usart) {
|
||||
/* Initialize the error USART */
|
||||
usart_dev *err_usart = __lm_enable_error_usart();
|
||||
|
||||
/* Print failed assert message */
|
||||
usart_putstr(err_usart, "ERROR: FAILED ASSERT(");
|
||||
usart_putstr(err_usart, exp);
|
||||
usart_putstr(err_usart, "): ");
|
||||
usart_putstr(err_usart, file);
|
||||
usart_putstr(err_usart, ": ");
|
||||
usart_putudec(err_usart, line);
|
||||
usart_putc(err_usart, '\n');
|
||||
usart_putc(err_usart, '\r');
|
||||
}
|
||||
/* Shutdown and error fade */
|
||||
__error();
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide an __assert_func handler to libc so that calls to assert()
|
||||
* get redirected to _fail.
|
||||
*/
|
||||
void __assert_func(const char* file, int line, const char* method,
|
||||
const char* expression) {
|
||||
_fail(file, line, expression);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide an abort() implementation that aborts execution and punts
|
||||
* to __error().
|
||||
*/
|
||||
void abort() {
|
||||
if (__lm_enable_error_usart) {
|
||||
/* Initialize the error USART */
|
||||
usart_dev *err_usart = __lm_enable_error_usart();
|
||||
/* Print abort message. */
|
||||
usart_putstr(err_usart, "ERROR: PROGRAM ABORTED VIA abort()\r\n");
|
||||
}
|
||||
|
||||
/* Shutdown and error fade */
|
||||
__error();
|
||||
}
|
||||
|
||||
/* This was public as of v0.0.12, so we've got to keep it public. */
|
||||
/**
|
||||
* @brief Fades the error LED on and off
|
||||
* @sideeffect Sets output push-pull on ERROR_LED_PIN.
|
||||
*/
|
||||
__attribute__((noreturn)) void throb(void) {
|
||||
#ifdef HAVE_ERROR_LED
|
||||
int32 slope = 1;
|
||||
uint32 CC = 0x0000;
|
||||
uint32 TOP_CNT = 0x0200;
|
||||
uint32 i = 0;
|
||||
|
||||
gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT);
|
||||
/* Error fade. */
|
||||
while (1) {
|
||||
if (CC == TOP_CNT) {
|
||||
slope = -1;
|
||||
} else if (CC == 0) {
|
||||
slope = 1;
|
||||
}
|
||||
|
||||
if (i == TOP_CNT) {
|
||||
CC += slope;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (i < CC) {
|
||||
gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1);
|
||||
} else {
|
||||
gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
#else
|
||||
/* No error LED is defined; do nothing. */
|
||||
while (1)
|
||||
;
|
||||
#endif
|
||||
}
|
44
BootLoaders/Boards/stm32/cores/maple/main.cpp
Normal file
44
BootLoaders/Boards/stm32/cores/maple/main.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 LeafLabs LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
extern void setup(void);
|
||||
extern void loop(void);
|
||||
extern void init(void);
|
||||
|
||||
// Force init to be called *first*, i.e. before static object allocation.
|
||||
// Otherwise, statically allocated objects that need libmaple may fail.
|
||||
__attribute__(( constructor (101))) void premain() {
|
||||
init();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
setup();
|
||||
|
||||
while (1) {
|
||||
loop();
|
||||
}
|
||||
return 0;
|
||||
}
|
36
BootLoaders/Boards/stm32/cores/maple/new.cpp
Normal file
36
BootLoaders/Boards/stm32/cores/maple/new.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2014 Arduino. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *operator new(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void * ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void * ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
61
BootLoaders/Boards/stm32/cores/maple/pwm.cpp
Normal file
61
BootLoaders/Boards/stm32/cores/maple/pwm.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/pwm.cpp
|
||||
* @brief Wiring-style pwmWrite().
|
||||
*/
|
||||
|
||||
#include "pwm.h"
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
#include <libmaple/timer.h>
|
||||
|
||||
#include "boards.h"
|
||||
#include "io.h"
|
||||
|
||||
void pwmWrite(uint8 pin, uint16 duty_cycle) {
|
||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||
return;
|
||||
}
|
||||
timer_dev *dev = PIN_MAP[pin].timer_device;
|
||||
uint8 cc_channel = PIN_MAP[pin].timer_channel;
|
||||
ASSERT(dev && cc_channel);
|
||||
timer_set_compare(dev, cc_channel, duty_cycle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Roger Clark. Added new function to replicate more closely what the Arduino API does
|
||||
* Note. This implementation is currently slower than it could be,
|
||||
* because pinMode needs to be called to set the special (new) mode of PWM
|
||||
* Some optimisation may be possible with pinMode or even in this function
|
||||
*/
|
||||
void analogWrite(uint8 pin, int duty_cycle8)
|
||||
{
|
||||
pinMode(pin,PWM);
|
||||
pwmWrite(pin,duty_cycle8 * 257);// 257 maps 255 to 65535 (i.e 255*257 = 65535)
|
||||
}
|
59
BootLoaders/Boards/stm32/cores/maple/pwm.h
Normal file
59
BootLoaders/Boards/stm32/cores/maple/pwm.h
Normal file
@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/include/wirish/pwm.h
|
||||
* @brief Wiring-style PWM interface.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_PWM_H_
|
||||
#define _WIRISH_PWM_H_
|
||||
|
||||
#include <libmaple/libmaple_types.h>
|
||||
|
||||
/**
|
||||
* Set the PWM duty on the given pin.
|
||||
*
|
||||
* User code is expected to determine and honor the maximum value
|
||||
* (based on the configured period).
|
||||
*
|
||||
* @param pin PWM output pin
|
||||
* @param duty_cycle Duty cycle to set. (Range is 0 to 65535)
|
||||
*/
|
||||
void pwmWrite(uint8 pin, uint16 duty_cycle16);
|
||||
|
||||
/**
|
||||
* Roger Clark. 20140103
|
||||
* Added function to replicate the Arduino PWM functionality or range 0 to 255
|
||||
* User code is expected to determine and honor the maximum value
|
||||
* (based on the configured period).
|
||||
*
|
||||
* @param pin PWM output pin
|
||||
* @param duty_cycle Duty cycle to set. (Range is 0 to 255)
|
||||
*/
|
||||
void analogWrite(uint8 pin, int duty_cycle8);
|
||||
#endif
|
||||
|
62
BootLoaders/Boards/stm32/cores/maple/rules.mk
Normal file
62
BootLoaders/Boards/stm32/cores/maple/rules.mk
Normal file
@ -0,0 +1,62 @@
|
||||
# Standard things
|
||||
sp := $(sp).x
|
||||
dirstack_$(sp) := $(d)
|
||||
d := $(dir)
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)
|
||||
|
||||
# Add board directory and MCU-specific directory to BUILDDIRS. These
|
||||
# are in subdirectories, but they're logically part of the Wirish
|
||||
# submodule.
|
||||
WIRISH_BOARD_PATH := boards/$(BOARD)
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)/$(WIRISH_BOARD_PATH)
|
||||
BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES)
|
||||
|
||||
# Safe includes for Wirish.
|
||||
WIRISH_INCLUDES := -I$(d)/include -I$(d)/$(WIRISH_BOARD_PATH)/include
|
||||
|
||||
# Local flags. Add -I$(d) to allow for private includes.
|
||||
CFLAGS_$(d) := $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -I$(d)
|
||||
|
||||
# Local rules and targets
|
||||
sSRCS_$(d) := start.S
|
||||
cSRCS_$(d) := start_c.c
|
||||
cSRCS_$(d) += syscalls.c
|
||||
cSRCS_$(d) += $(MCU_SERIES)/util_hooks.c
|
||||
cppSRCS_$(d) := boards.cpp
|
||||
cppSRCS_$(d) += cxxabi-compat.cpp
|
||||
cppSRCS_$(d) += ext_interrupts.cpp
|
||||
cppSRCS_$(d) += HardwareSerial.cpp
|
||||
cppSRCS_$(d) += HardwareTimer.cpp
|
||||
cppSRCS_$(d) += Print.cpp
|
||||
cppSRCS_$(d) += pwm.cpp
|
||||
ifeq ($(MCU_SERIES), stm32f1)
|
||||
cppSRCS_$(d) += usb_serial.cpp # HACK: this is currently STM32F1 only.
|
||||
cppSRCS_$(d) += HardwareSPI.cpp # FIXME: port to F2 and fix wirish.h
|
||||
endif
|
||||
cppSRCS_$(d) += wirish_analog.cpp
|
||||
cppSRCS_$(d) += wirish_digital.cpp
|
||||
cppSRCS_$(d) += wirish_math.cpp
|
||||
cppSRCS_$(d) += wirish_shift.cpp
|
||||
cppSRCS_$(d) += wirish_time.cpp
|
||||
cppSRCS_$(d) += $(MCU_SERIES)/boards_setup.cpp
|
||||
cppSRCS_$(d) += $(MCU_SERIES)/wirish_digital.cpp
|
||||
cppSRCS_$(d) += $(MCU_SERIES)/wirish_debug.cpp
|
||||
cppSRCS_$(d) += $(WIRISH_BOARD_PATH)/board.cpp
|
||||
|
||||
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
|
||||
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
|
||||
cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%)
|
||||
|
||||
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
|
||||
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \
|
||||
$(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o)
|
||||
DEPS_$(d) := $(OBJS_$(d):%.o=%.d)
|
||||
|
||||
$(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d))
|
||||
|
||||
TGT_BIN += $(OBJS_$(d))
|
||||
|
||||
# Standard things
|
||||
-include $(DEPS_$(d))
|
||||
d := $(dirstack_$(sp))
|
||||
sp := $(basename $(sp))
|
198
BootLoaders/Boards/stm32/cores/maple/sdio.cpp
Normal file
198
BootLoaders/Boards/stm32/cores/maple/sdio.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/******************************************************************************
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file libmaple/sdio.c
|
||||
* @author stevstrong
|
||||
* @brief Secure digital input/output interface.
|
||||
*/
|
||||
|
||||
#include <libmaple/sdio.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <boards.h>
|
||||
#include "wirish.h"
|
||||
|
||||
|
||||
//#include <libmaple/libmaple.h>
|
||||
//#include <libmaple/rcc.h>
|
||||
//#include <series/gpio.h>
|
||||
//#include "wirish.h"
|
||||
//#include "boards.h"
|
||||
//
|
||||
|
||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
||||
|
||||
sdio_dev * SDIO = SDIO_BASE;
|
||||
|
||||
#define DELAY_LONG 10
|
||||
#define DELAY_SHORT 1
|
||||
|
||||
uint8_t dly = DELAY_LONG; // microseconds delay after accessing registers
|
||||
|
||||
/*
|
||||
* SDIO convenience routines
|
||||
*/
|
||||
void sdio_gpios_init(void)
|
||||
{
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D0].gpio_device, PIN_MAP[BOARD_SDIO_D0].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_CLK].gpio_device, PIN_MAP[BOARD_SDIO_CLK].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_CMD].gpio_device, PIN_MAP[BOARD_SDIO_CMD].gpio_bit, GPIO_AF_OUTPUT_PP);
|
||||
/*
|
||||
* Todo just remove it, not needed for F1.
|
||||
*/
|
||||
/*
|
||||
gpio_set_af_mode(BOARD_SDIO_D0, 12);
|
||||
gpio_set_af_mode(BOARD_SDIO_D1, 12);
|
||||
gpio_set_af_mode(BOARD_SDIO_D2, 12);
|
||||
gpio_set_af_mode(BOARD_SDIO_D3, 12);
|
||||
gpio_set_af_mode(BOARD_SDIO_CLK, 12);
|
||||
gpio_set_af_mode(BOARD_SDIO_CMD, 12);
|
||||
*/
|
||||
}
|
||||
|
||||
void sdio_gpios_deinit(void)
|
||||
{
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D0].gpio_device, PIN_MAP[BOARD_SDIO_D0].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D1].gpio_device, PIN_MAP[BOARD_SDIO_D1].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D2].gpio_device, PIN_MAP[BOARD_SDIO_D2].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_D3].gpio_device, PIN_MAP[BOARD_SDIO_D3].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_CLK].gpio_device, PIN_MAP[BOARD_SDIO_CLK].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
gpio_set_mode(PIN_MAP[BOARD_SDIO_CMD].gpio_device, PIN_MAP[BOARD_SDIO_CMD].gpio_bit, GPIO_INPUT_FLOATING);
|
||||
|
||||
/*
|
||||
* Todo just remove it, not needed for F1.
|
||||
*/
|
||||
/*
|
||||
gpio_set_af_mode(BOARD_SDIO_D0, 0);
|
||||
gpio_set_af_mode(BOARD_SDIO_D1, 0);
|
||||
gpio_set_af_mode(BOARD_SDIO_D2, 0);
|
||||
gpio_set_af_mode(BOARD_SDIO_D3, 0);
|
||||
gpio_set_af_mode(BOARD_SDIO_CLK, 0);
|
||||
gpio_set_af_mode(BOARD_SDIO_CMD, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize and reset the SDIO device.
|
||||
*/
|
||||
void sdio_init(void)
|
||||
{
|
||||
rcc_clk_enable(RCC_SDIO);
|
||||
rcc_reset_dev(RCC_SDIO);
|
||||
}
|
||||
|
||||
void sdio_power_on(void)
|
||||
{
|
||||
SDIO->POWER = SDIO_POWER_PWRCTRL_ON;
|
||||
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
|
||||
// plus two PCLK2 clock periods.
|
||||
delay_us(DELAY_LONG);
|
||||
}
|
||||
|
||||
void sdio_power_off(void)
|
||||
{
|
||||
SDIO->POWER = SDIO_POWER_PWRCTRL_OFF;
|
||||
// After a data write, data cannot be written to this register for three SDIOCLK clock periods
|
||||
// plus two PCLK2 clock periods.
|
||||
delay_us(DELAY_LONG);
|
||||
}
|
||||
|
||||
void sdio_set_clock(uint32_t clk)
|
||||
{
|
||||
if (clk>24000000UL) clk = 24000000UL; // limit the SDIO master clock to 24MHz
|
||||
|
||||
if (clk<1000000) dly = DELAY_LONG;
|
||||
else dly = DELAY_SHORT;
|
||||
|
||||
sdio_disable();
|
||||
SDIO->CLKCR = (SDIO->CLKCR & (~(SDIO_CLKCR_CLKDIV|SDIO_CLKCR_BYPASS))) | SDIO_CLKCR_CLKEN | (((SDIOCLK/clk)-2)&SDIO_CLKCR_CLKDIV);
|
||||
delay_us(dly);
|
||||
}
|
||||
|
||||
void sdio_set_dbus_width(uint16_t bus_w)
|
||||
{
|
||||
SDIO->CLKCR = (SDIO->CLKCR & (~SDIO_CLKCR_WIDBUS)) | bus_w;
|
||||
delay_us(dly);
|
||||
}
|
||||
|
||||
void sdio_set_dblock_size(uint8_t dbsize)
|
||||
{
|
||||
SDIO->DCTRL = (SDIO->DCTRL&(~SDIO_DCTRL_DBLOCKSIZE)) | ((dbsize&0xF)<<4);
|
||||
delay_us(dly);
|
||||
}
|
||||
|
||||
void sdio_enable(void)
|
||||
{
|
||||
SDIO->CLKCR |= SDIO_CLKCR_CLKEN;
|
||||
delay_us(dly);
|
||||
}
|
||||
|
||||
void sdio_disable(void)
|
||||
{
|
||||
SDIO->CLKCR ^= SDIO_CLKCR_CLKEN;
|
||||
delay_us(dly);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure and enable the SDIO device.
|
||||
*/
|
||||
void sdio_begin(void)
|
||||
{
|
||||
sdio_gpios_init();
|
||||
sdio_init();
|
||||
sdio_power_on();
|
||||
// Set initial SCK rate.
|
||||
sdio_set_clock(400000);
|
||||
delay_us(200); // generate 80 pulses at 400kHz
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the SDIO device.
|
||||
*/
|
||||
void sdio_end(void)
|
||||
{
|
||||
sdio_disable();
|
||||
while ( sdio_cmd_xfer_ongoing() );
|
||||
sdio_power_off();
|
||||
rcc_clk_disable(RCC_SDIO);
|
||||
sdio_gpios_deinit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send command by the SDIO device.
|
||||
*/
|
||||
uint8_t sdio_cmd_send(uint16_t cmd_index_resp_type, uint32_t arg)
|
||||
{
|
||||
uint8_t retries = 10; // in case of errors
|
||||
do { // retry command if errors detected
|
||||
// clear interrupt flags - IMPORTANT!!!
|
||||
SDIO->ICR = SDIO_ICR_CMD_FLAGS;
|
||||
// write command
|
||||
SDIO->ARG = arg;
|
||||
SDIO->CMD = (uint32_t)(SDIO_CMD_CPSMEN | cmd_index_resp_type );
|
||||
while ( (SDIO->STA&SDIO_STA_CMDACT) ) ; // wait for actual command transfer to finish
|
||||
// wait for response, if the case
|
||||
if ( cmd_index_resp_type&(SDIO_CMD_WAIT_SHORT_RESP|SDIO_CMD_WAIT_LONG_RESP) ) {
|
||||
while ( !(SDIO->STA&(SDIO_STA_CMDREND|SDIO_STA_CMD_ERROR_FLAGS)) ) ;
|
||||
} else break; // no response required
|
||||
if ( SDIO->STA&(SDIO_STA_CMDREND|SDIO_STA_CTIMEOUT) )
|
||||
break; // response received or timeout
|
||||
// ignore CRC error for CMD5 and ACMD41
|
||||
if ( ((cmd_index_resp_type&SDIO_CMD_CMDINDEX)==5) || ((cmd_index_resp_type&SDIO_CMD_CMDINDEX)==41) )
|
||||
break;
|
||||
} while ( (--retries) );
|
||||
return (uint8_t)retries;
|
||||
}
|
||||
|
||||
#endif // defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
83
BootLoaders/Boards/stm32/cores/maple/stm32f1/util_hooks.c
Normal file
83
BootLoaders/Boards/stm32/cores/maple/stm32f1/util_hooks.c
Normal file
@ -0,0 +1,83 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung (from libmaple/util.c).
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* STM32F1 implementations for libmaple/util.c hooks
|
||||
*
|
||||
* These need more love and attention before being made public API
|
||||
* (this includes being easily overridable by user code).
|
||||
*/
|
||||
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/stm32.h>
|
||||
#include <libmaple/timer.h>
|
||||
#include <libmaple/adc.h>
|
||||
#include <libmaple/usart.h>
|
||||
|
||||
/* Failed ASSERT()s send out a message using this USART config. */
|
||||
#ifndef ERROR_USART
|
||||
#define ERROR_USART USART2
|
||||
#define ERROR_USART_BAUD 9600
|
||||
#define ERROR_TX_PORT GPIOA
|
||||
#define ERROR_TX_PIN 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disables all peripheral interrupts except USB (when available),
|
||||
* turns off commonly-used peripherals. Called by __error() with
|
||||
* global interrupts disabled.
|
||||
*/
|
||||
void __lm_error(void) {
|
||||
/* Turn off peripheral interrupts */
|
||||
nvic_irq_disable_all();
|
||||
|
||||
/* Turn off timers */
|
||||
timer_disable_all();
|
||||
|
||||
/* Turn off ADC */
|
||||
adc_disable_all();
|
||||
|
||||
/* Turn off all USARTs */
|
||||
usart_disable_all();
|
||||
|
||||
#if STM32_HAVE_USB
|
||||
/* Turn the USB interrupt back on so the bootloader keeps on functioning */
|
||||
nvic_irq_enable(NVIC_USB_HP_CAN_TX);
|
||||
nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the error USART for writing.
|
||||
*/
|
||||
usart_dev* __lm_enable_error_usart() {
|
||||
gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_AF_OUTPUT_PP);
|
||||
usart_init(ERROR_USART);
|
||||
usart_set_baud_rate(ERROR_USART, USART_USE_PCLK, ERROR_USART_BAUD);
|
||||
return ERROR_USART;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
#include <wiring_pulse.h>
|
||||
#include "boards.h"
|
||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
||||
* to 3 minutes in length, but must be called at least a few dozen microseconds
|
||||
* before the start of the pulse. */
|
||||
|
||||
|
||||
/*
|
||||
* Roger Clark
|
||||
*
|
||||
* Note. The API spec for this function published on http://www.arduino.cc/en/Reference/PulseIn
|
||||
* doesn't reflect what either the AVR or SAM version of this function actualy do with regard to the timeout value
|
||||
*
|
||||
* "timeout (optional): the number of microseconds to wait for the pulse to start; default is one second (unsigned long) "
|
||||
*
|
||||
* Because the timeout, is actually coded as the total time to both wait while the input is in the state requested
|
||||
* then wait for the opposite state duration
|
||||
* then count the length of the pulse when it has the value of state (HIGH or LOW)
|
||||
*
|
||||
* So I think the code for both the AVR and the Due is wrong in that it doesnt match the spec
|
||||
*
|
||||
* I have done basically the same as the AVR and Due code, except to make the timeout a bit more accurate I have put in a dummy volatile varable
|
||||
* dummyWidth so that both the waiting while loops take the same number of clock cycles to execute as the acount width counting loop
|
||||
*
|
||||
* to be slighly more accurate the maxLoops variable really needs to take into account the loop setup code, but its probably as good as necessary
|
||||
*
|
||||
*/
|
||||
uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
|
||||
{
|
||||
// cache the port and bit of the pin in order to speed up the
|
||||
// pulse width measuring loop and achieve finer resolution. calling
|
||||
// digitalRead() instead yields much coarser resolution.
|
||||
|
||||
gpio_dev *dev=PIN_MAP[pin].gpio_device;
|
||||
uint32_t bit = (1U << PIN_MAP[pin].gpio_bit);
|
||||
|
||||
|
||||
uint32_t width = 0; // keep initialization out of time critical area
|
||||
|
||||
// convert the timeout from microseconds to a number of times through
|
||||
// the initial loop; it takes 16 clock cycles per iteration.
|
||||
uint32_t numloops = 0;
|
||||
uint32_t maxloops = timeout * ( F_CPU / 16000000);
|
||||
volatile uint32_t dummyWidth=0;
|
||||
|
||||
// wait for any previous pulse to end
|
||||
while ( (dev->regs->IDR & bit) == bit) {
|
||||
if (numloops++ == maxloops) {
|
||||
return 0;
|
||||
}
|
||||
dummyWidth++;
|
||||
}
|
||||
|
||||
// wait for the pulse to start
|
||||
while ((dev->regs->IDR & bit) != bit) {
|
||||
if (numloops++ == maxloops) {
|
||||
return 0;
|
||||
}
|
||||
dummyWidth++;
|
||||
}
|
||||
|
||||
// wait for the pulse to stop
|
||||
while ((dev->regs->IDR & bit) == bit) {
|
||||
if (numloops++ == maxloops) {
|
||||
return 0;
|
||||
}
|
||||
width++;
|
||||
}
|
||||
|
||||
// Excluding time taking up by the interrupts, it needs 16 clock cycles to look through the last while loop
|
||||
// 5 is added as a fiddle factor to correct for interrupts etc. But ultimately this would only be accurate if it was done ona hardware timer
|
||||
|
||||
return (uint32_t)( ( (unsigned long long)(width+5) * (unsigned long long) 16000000.0) /(unsigned long long)F_CPU ) ;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/stm32f1/wirish_debug.cpp
|
||||
* @brief High level debug port configuration
|
||||
*/
|
||||
|
||||
#include <wirish_debug.h>
|
||||
#include <libmaple/gpio.h>
|
||||
|
||||
void disableDebugPorts(void) {
|
||||
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
|
||||
}
|
||||
|
||||
void enableDebugPorts(void) {
|
||||
afio_cfg_debug_ports(AFIO_DEBUG_FULL_SWJ);
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* STM32F1 implementations for basic GPIO functionality.
|
||||
*/
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
#include <libmaple/timer.h>
|
||||
|
||||
#include <boards.h>
|
||||
|
||||
void pinMode(uint8 pin, WiringPinMode mode) {
|
||||
gpio_pin_mode outputMode;
|
||||
bool pwm = false;
|
||||
|
||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case OUTPUT:
|
||||
outputMode = GPIO_OUTPUT_PP;
|
||||
break;
|
||||
case OUTPUT_OPEN_DRAIN:
|
||||
outputMode = GPIO_OUTPUT_OD;
|
||||
break;
|
||||
case INPUT:
|
||||
case INPUT_FLOATING:
|
||||
outputMode = GPIO_INPUT_FLOATING;
|
||||
break;
|
||||
case INPUT_ANALOG:
|
||||
outputMode = GPIO_INPUT_ANALOG;
|
||||
break;
|
||||
case INPUT_PULLUP:
|
||||
outputMode = GPIO_INPUT_PU;
|
||||
break;
|
||||
case INPUT_PULLDOWN:
|
||||
outputMode = GPIO_INPUT_PD;
|
||||
break;
|
||||
case PWM:
|
||||
outputMode = GPIO_AF_OUTPUT_PP;
|
||||
pwm = true;
|
||||
break;
|
||||
case PWM_OPEN_DRAIN:
|
||||
outputMode = GPIO_AF_OUTPUT_OD;
|
||||
pwm = true;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode);
|
||||
|
||||
if (PIN_MAP[pin].timer_device != NULL) {
|
||||
if ( pwm ) { // we're switching into PWM, enable timer channels
|
||||
timer_set_mode(PIN_MAP[pin].timer_device,
|
||||
PIN_MAP[pin].timer_channel,
|
||||
TIMER_PWM );
|
||||
} else { // disable channel output in non pwm-Mode
|
||||
timer_cc_disable(PIN_MAP[pin].timer_device,
|
||||
PIN_MAP[pin].timer_channel);
|
||||
}
|
||||
}
|
||||
}
|
204
BootLoaders/Boards/stm32/cores/maple/tone.cpp
Normal file
204
BootLoaders/Boards/stm32/cores/maple/tone.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// tone(pin,frequency[,duration]) generate a tone on a given pin
|
||||
//
|
||||
// noTone(pin) switch off the tone on the pin
|
||||
//
|
||||
// setToneTimerChannel(timer,channel) force use of given timer/channel
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <HardwareTimer.h>
|
||||
|
||||
|
||||
#define PinTimer(pin) (PIN_MAP[pin].timer_device->clk_id-RCC_TIMER1+1)
|
||||
#define PinChannel(pin) (PIN_MAP[pin].timer_channel)
|
||||
|
||||
// if USE_PIN_TIMER is set, the PWM timer/channel is used for PWM pins
|
||||
#define USE_PIN_TIMER
|
||||
|
||||
// if USE_BSRR is set the tone pin will be written via the fast BSRR register
|
||||
// instead of using the slow digitalWrite() function in the interrupt handler
|
||||
#define USE_BSRR
|
||||
|
||||
// construct static timer array (
|
||||
|
||||
|
||||
#ifdef STM32_HIGH_DENSITY
|
||||
// define default timer and channel
|
||||
#ifndef TONE_TIMER
|
||||
#define TONE_TIMER 8
|
||||
#endif
|
||||
#ifndef TONE_CHANNEL
|
||||
#define TONE_CHANNEL 8
|
||||
#endif
|
||||
|
||||
HardwareTimer TTimer1(1), TTimer2(2), TTimer3(3), TTimer4(4),TTimer5(5), TTimer6(6), TTimer7(7), TTimer8(8);
|
||||
HardwareTimer *TTimer[8] = { &TTimer1,&TTimer2,&TTimer3,&TTimer4,&TTimer5,&TTimer6,&TTimer7,&TTimer8 };
|
||||
#else
|
||||
// define default timer and channel
|
||||
#ifndef TONE_TIMER
|
||||
#define TONE_TIMER 4
|
||||
#endif
|
||||
#ifndef TONE_CHANNEL
|
||||
#define TONE_CHANNEL 4
|
||||
#endif
|
||||
|
||||
HardwareTimer TTimer1(1), TTimer2(2), TTimer3(3), TTimer4(4);
|
||||
HardwareTimer *TTimer[4] = { &TTimer1,&TTimer2,&TTimer3,&TTimer4 };
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t tone_force_channel = 0; // forced timer channel
|
||||
uint8_t tone_force_ntimer = 0; // forced timer
|
||||
|
||||
HardwareTimer *tone_timer;// = TTimer[TONE_TIMER-1]; // timer used to generate frequency
|
||||
uint8_t tone_channel = TONE_CHANNEL; // timer channel used to generate frequency
|
||||
uint8_t tone_ntimer = TONE_TIMER; // timer used to generate frequency
|
||||
|
||||
bool tone_state = true; // last pin state for toggling
|
||||
short tone_pin = -1; // pin for outputting sound
|
||||
short tone_freq = 444; // tone frequency (0=pause)
|
||||
volatile uint32_t tone_nhw = 0; // tone duration in number of half waves
|
||||
uint16_t tone_tcount = 0; // time between handler calls in 1/36 usec
|
||||
uint16_t tone_ncount = 0; // handler call between toggling
|
||||
uint16_t tone_n = 0; // remaining handler calls before toggling
|
||||
uint32_t tone_next = 0; // counter value of next interrupt
|
||||
|
||||
#ifdef USE_BSRR
|
||||
volatile uint32_t *tone_bsrr; // BSRR set register (lower 16 bits)
|
||||
uint32_t tone_smask=0; // BSRR set bitmask
|
||||
uint32_t tone_rmask=0; // BSRR reset bitmask
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// timer hander for tone with no duration specified,
|
||||
// will keep going until noTone() is called
|
||||
void tone_handler_1(void) {
|
||||
tone_next += tone_tcount; // comparator value for next interrupt
|
||||
tone_timer->setCompare(tone_channel, tone_next); // and install it
|
||||
if(--tone_n == 0){
|
||||
tone_state = !tone_state; // toggle tone output
|
||||
|
||||
#ifdef USE_BSRR
|
||||
if(tone_state)
|
||||
*tone_bsrr = tone_smask;
|
||||
else
|
||||
*tone_bsrr = tone_rmask;
|
||||
#else
|
||||
digitalWrite(tone_pin,tone_state);// and output it
|
||||
#endif
|
||||
|
||||
tone_n = tone_ncount; // reset interrupt counter
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// timer hander for tone with a specified duration,
|
||||
// will stop automatically when duration time is up.
|
||||
void tone_handler_2(void) {
|
||||
tone_next += tone_tcount;
|
||||
tone_timer->setCompare(tone_channel, tone_next);
|
||||
if(--tone_n == 0){
|
||||
if(tone_freq>0){ // toggle pin
|
||||
tone_state = !tone_state;
|
||||
#ifdef USE_BSRR
|
||||
if(tone_state)
|
||||
*tone_bsrr = tone_smask;
|
||||
else
|
||||
*tone_bsrr = tone_rmask;
|
||||
#else
|
||||
digitalWrite(tone_pin,tone_state);// and output it
|
||||
#endif
|
||||
}
|
||||
tone_n = tone_ncount;
|
||||
if(!--tone_nhw){ // check if tone duration has finished
|
||||
tone_timer->pause(); // disable timer
|
||||
pinMode(tone_pin, INPUT); // disable tone pin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// play a tone on given pin with given frequency and optional duration in msec
|
||||
void tone(uint32_t pin, uint32_t freq, uint32_t duration) {
|
||||
tone_pin = pin;
|
||||
|
||||
#ifdef USE_PIN_TIMER
|
||||
// if the pin has a PWM timer/channel, use it (unless the timer/channel are forced)
|
||||
if(PinChannel(tone_pin) && !tone_force_channel){
|
||||
tone_channel = PinChannel(tone_pin);
|
||||
tone_ntimer = PinTimer(tone_pin);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// set timer and channel to default resp values forced with setToneTimerChannel
|
||||
tone_ntimer = tone_force_channel?tone_force_ntimer:TONE_TIMER;
|
||||
tone_channel = tone_force_channel?tone_force_channel:TONE_CHANNEL;
|
||||
}
|
||||
|
||||
tone_timer = TTimer[tone_ntimer-1];
|
||||
tone_freq = freq;
|
||||
tone_nhw = 0;
|
||||
tone_next = 0;
|
||||
|
||||
tone_timer->pause();
|
||||
|
||||
if(freq > 0){
|
||||
uint32_t count = (F_CPU/4)/freq; // timer counts per half wave
|
||||
tone_ncount = tone_n = (count>>16)+1; // number of 16-bit count chunk
|
||||
tone_tcount = count/tone_ncount; // size of count chunk
|
||||
if(duration > 0) // number of half waves to be generated
|
||||
tone_nhw = ((duration*freq)/1000)<<1;
|
||||
else // no duration specified, continuous sound until noTone() called
|
||||
tone_nhw = 0;
|
||||
|
||||
pinMode(tone_pin, PWM); // configure output pin
|
||||
pinMode(tone_pin, OUTPUT); // configure output pin
|
||||
|
||||
#ifdef USE_BSRR
|
||||
// Set up BSRR register values for fast ISR
|
||||
tone_bsrr = &((PIN_MAP[tone_pin].gpio_device)->regs->BSRR);
|
||||
tone_smask = (BIT(PIN_MAP[tone_pin].gpio_bit));
|
||||
tone_rmask = tone_smask<<16;
|
||||
#endif
|
||||
|
||||
// Set up an interrupt on given timer and channel
|
||||
tone_next = tone_tcount; // prepare channel compare register
|
||||
tone_timer->setMode(tone_channel,TIMER_OUTPUT_COMPARE);
|
||||
tone_timer->setCompare(tone_channel,tone_next);
|
||||
// attach corresponding handler routine
|
||||
tone_timer->attachInterrupt(tone_channel,tone_nhw?tone_handler_2:tone_handler_1);
|
||||
|
||||
// Refresh the tone timer
|
||||
tone_timer->refresh();
|
||||
|
||||
// Start the timer counting
|
||||
tone_timer->resume();
|
||||
|
||||
} else {
|
||||
|
||||
// detach handler routine
|
||||
tone_timer->detachInterrupt(tone_channel);
|
||||
// disactive pin by configuring it as input
|
||||
pinMode(tone_pin, INPUT);
|
||||
|
||||
}
|
||||
while(tone_nhw) ; // blocks till duration elapsed
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// disable tone on specified pin, if any
|
||||
void noTone(uint32_t pin){
|
||||
tone(pin,0,0); // it's all handled in tone()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// set timer and channel to some different value
|
||||
// must be called before calling tone() or after noTone() was called
|
||||
void setToneTimerChannel(uint8_t ntimer, uint8_t channel){
|
||||
tone_force_ntimer = ntimer;
|
||||
tone_force_channel = channel;
|
||||
}
|
28
BootLoaders/Boards/stm32/cores/maple/tone.h
Normal file
28
BootLoaders/Boards/stm32/cores/maple/tone.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2015 Arduino LLC. All right reserved.
|
||||
|
||||
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 2.1 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
void tone(uint32_t _pin, uint32_t frequency, uint32_t duration = 0);
|
||||
void noTone(uint32_t _pin);
|
||||
|
||||
#endif
|
359
BootLoaders/Boards/stm32/cores/maple/usb_serial.cpp
Normal file
359
BootLoaders/Boards/stm32/cores/maple/usb_serial.cpp
Normal file
@ -0,0 +1,359 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief USB virtual serial terminal
|
||||
*/
|
||||
|
||||
#include "usb_serial.h"
|
||||
|
||||
#include "string.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#include <libmaple/nvic.h>
|
||||
#include <libmaple/usb_cdcacm.h>
|
||||
#include <libmaple/usb.h>
|
||||
#include <libmaple/iwdg.h>
|
||||
|
||||
#include "wirish.h"
|
||||
|
||||
/*
|
||||
* Hooks used for bootloader reset signalling
|
||||
*/
|
||||
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
static void rxHook(unsigned, void*);
|
||||
static void ifaceSetupHook(unsigned, void*);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* USBSerial interface
|
||||
*/
|
||||
|
||||
#define USB_TIMEOUT 50
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
bool USBSerial::_hasBegun = false;
|
||||
#endif
|
||||
|
||||
USBSerial::USBSerial(void) {
|
||||
#if !BOARD_HAVE_SERIALUSB
|
||||
ASSERT(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void USBSerial::begin(void) {
|
||||
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
if (_hasBegun)
|
||||
return;
|
||||
_hasBegun = true;
|
||||
|
||||
usb_cdcacm_enable(BOARD_USB_DISC_DEV, (uint8_t)BOARD_USB_DISC_BIT);
|
||||
usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, rxHook);
|
||||
usb_cdcacm_set_hooks(USB_CDCACM_HOOK_IFACE_SETUP, ifaceSetupHook);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Roger Clark. Two new begin functions has been added so that normal Arduino Sketches that use Serial.begin(xxx) will compile.
|
||||
void USBSerial::begin(unsigned long ignoreBaud)
|
||||
{
|
||||
volatile unsigned long removeCompilerWarningsIgnoreBaud=ignoreBaud;
|
||||
|
||||
ignoreBaud=removeCompilerWarningsIgnoreBaud;
|
||||
begin();
|
||||
}
|
||||
void USBSerial::begin(unsigned long ignoreBaud, uint8_t ignore)
|
||||
{
|
||||
volatile unsigned long removeCompilerWarningsIgnoreBaud=ignoreBaud;
|
||||
volatile uint8_t removeCompilerWarningsIgnore=ignore;
|
||||
|
||||
ignoreBaud=removeCompilerWarningsIgnoreBaud;
|
||||
ignore=removeCompilerWarningsIgnore;
|
||||
begin();
|
||||
}
|
||||
|
||||
void USBSerial::end(void) {
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
usb_cdcacm_disable(BOARD_USB_DISC_DEV, (uint8_t)BOARD_USB_DISC_BIT);
|
||||
usb_cdcacm_remove_hooks(USB_CDCACM_HOOK_RX | USB_CDCACM_HOOK_IFACE_SETUP);
|
||||
_hasBegun = false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
size_t USBSerial::write(uint8 ch) {
|
||||
size_t n = 0;
|
||||
this->write(&ch, 1);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t USBSerial::write(const char *str) {
|
||||
size_t n = 0;
|
||||
this->write((const uint8*)str, strlen(str));
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t USBSerial::write(const uint8 *buf, uint32 len)
|
||||
{
|
||||
size_t n = 0;
|
||||
if (!(bool) *this || !buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 txed = 0;
|
||||
while (txed < len) {
|
||||
txed += usb_cdcacm_tx((const uint8*)buf + txed, len - txed);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int USBSerial::available(void) {
|
||||
return usb_cdcacm_data_available();
|
||||
}
|
||||
|
||||
int USBSerial::peek(void)
|
||||
{
|
||||
uint8 b;
|
||||
if (usb_cdcacm_peek(&b, 1)==1)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void USBSerial::flush(void)
|
||||
{
|
||||
/*Roger Clark. Rather slow method. Need to improve this */
|
||||
uint8 b;
|
||||
while(usb_cdcacm_data_available())
|
||||
{
|
||||
this->read(&b, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 USBSerial::read(uint8 * buf, uint32 len) {
|
||||
uint32 rxed = 0;
|
||||
while (rxed < len) {
|
||||
rxed += usb_cdcacm_rx(buf + rxed, len - rxed);
|
||||
}
|
||||
|
||||
return rxed;
|
||||
}
|
||||
|
||||
size_t USBSerial::readBytes(char *buf, const size_t& len)
|
||||
{
|
||||
size_t rxed=0;
|
||||
unsigned long startMillis;
|
||||
startMillis = millis();
|
||||
if (len <= 0) return 0;
|
||||
do {
|
||||
rxed += usb_cdcacm_rx((uint8 *)buf + rxed, len - rxed);
|
||||
if (rxed == len) return rxed;
|
||||
} while(millis() - startMillis < _timeout);
|
||||
return rxed;
|
||||
}
|
||||
|
||||
/* Blocks forever until 1 byte is received */
|
||||
int USBSerial::read(void) {
|
||||
uint8 b;
|
||||
/*
|
||||
this->read(&b, 1);
|
||||
return b;
|
||||
*/
|
||||
|
||||
if (usb_cdcacm_rx(&b, 1)==0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 USBSerial::pending(void) {
|
||||
return usb_cdcacm_get_pending();
|
||||
}
|
||||
|
||||
uint8 USBSerial::getDTR(void) {
|
||||
return usb_cdcacm_get_dtr();
|
||||
}
|
||||
|
||||
uint8 USBSerial::getRTS(void) {
|
||||
return usb_cdcacm_get_rts();
|
||||
}
|
||||
|
||||
USBSerial::operator bool() {
|
||||
return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr();
|
||||
}
|
||||
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
#ifdef SERIAL_USB
|
||||
USBSerial Serial;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bootloader hook implementations
|
||||
*/
|
||||
|
||||
#if BOARD_HAVE_SERIALUSB
|
||||
|
||||
enum reset_state_t {
|
||||
DTR_UNSET,
|
||||
DTR_HIGH,
|
||||
DTR_NEGEDGE,
|
||||
DTR_LOW
|
||||
};
|
||||
|
||||
static reset_state_t reset_state = DTR_UNSET;
|
||||
|
||||
static void ifaceSetupHook(unsigned hook, void *requestvp) {
|
||||
uint8 request = *(uint8*)requestvp;
|
||||
|
||||
// Ignore requests we're not interested in.
|
||||
if (request != USB_CDCACM_SET_CONTROL_LINE_STATE) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SERIAL_USB
|
||||
// We need to see a negative edge on DTR before we start looking
|
||||
// for the in-band magic reset byte sequence.
|
||||
uint8 dtr = usb_cdcacm_get_dtr();
|
||||
switch (reset_state) {
|
||||
case DTR_UNSET:
|
||||
reset_state = dtr ? DTR_HIGH : DTR_LOW;
|
||||
break;
|
||||
case DTR_HIGH:
|
||||
reset_state = dtr ? DTR_HIGH : DTR_NEGEDGE;
|
||||
break;
|
||||
case DTR_NEGEDGE:
|
||||
reset_state = dtr ? DTR_HIGH : DTR_LOW;
|
||||
break;
|
||||
case DTR_LOW:
|
||||
reset_state = dtr ? DTR_HIGH : DTR_LOW;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_robotis)
|
||||
uint8 dtr = usb_cdcacm_get_dtr();
|
||||
uint8 rts = usb_cdcacm_get_rts();
|
||||
|
||||
if (rts && !dtr) {
|
||||
reset_state = DTR_NEGEDGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((usb_cdcacm_get_baud() == 1200) && (reset_state == DTR_NEGEDGE)) {
|
||||
iwdg_init(IWDG_PRE_4, 10);
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
#define RESET_DELAY 100000
|
||||
#ifdef SERIAL_USB
|
||||
static void wait_reset(void) {
|
||||
delay_us(RESET_DELAY);
|
||||
nvic_sys_reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define STACK_TOP 0x20000800
|
||||
#define EXC_RETURN 0xFFFFFFF9
|
||||
#define DEFAULT_CPSR 0x61000000
|
||||
static void rxHook(unsigned hook, void *ignored) {
|
||||
/* FIXME this is mad buggy; we need a new reset sequence. E.g. NAK
|
||||
* after each RX means you can't reset if any bytes are waiting. */
|
||||
if (reset_state == DTR_NEGEDGE) {
|
||||
reset_state = DTR_LOW;
|
||||
|
||||
if (usb_cdcacm_data_available() >= 4) {
|
||||
// The magic reset sequence is "1EAF".
|
||||
#ifdef SERIAL_USB
|
||||
static const uint8 magic[4] = {'1', 'E', 'A', 'F'};
|
||||
#else
|
||||
#if defined(BOOTLOADER_robotis)
|
||||
static const uint8 magic[4] = {'C', 'M', '9', 'X'};
|
||||
#else
|
||||
static const uint8 magic[4] = {'1', 'E', 'A', 'F'};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint8 chkBuf[4];
|
||||
|
||||
// Peek at the waiting bytes, looking for reset sequence,
|
||||
// bailing on mismatch.
|
||||
usb_cdcacm_peek_ex(chkBuf, usb_cdcacm_data_available() - 4, 4);
|
||||
for (unsigned i = 0; i < sizeof(magic); i++) {
|
||||
if (chkBuf[i] != magic[i]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_USB
|
||||
// Got the magic sequence -> reset, presumably into the bootloader.
|
||||
// Return address is wait_reset, but we must set the thumb bit.
|
||||
uintptr_t target = (uintptr_t)wait_reset | 0x1;
|
||||
asm volatile("mov r0, %[stack_top] \n\t" // Reset stack
|
||||
"mov sp, r0 \n\t"
|
||||
"mov r0, #1 \n\t"
|
||||
"mov r1, %[target_addr] \n\t"
|
||||
"mov r2, %[cpsr] \n\t"
|
||||
"push {r2} \n\t" // Fake xPSR
|
||||
"push {r1} \n\t" // PC target addr
|
||||
"push {r0} \n\t" // Fake LR
|
||||
"push {r0} \n\t" // Fake R12
|
||||
"push {r0} \n\t" // Fake R3
|
||||
"push {r0} \n\t" // Fake R2
|
||||
"push {r0} \n\t" // Fake R1
|
||||
"push {r0} \n\t" // Fake R0
|
||||
"mov lr, %[exc_return] \n\t"
|
||||
"bx lr"
|
||||
:
|
||||
: [stack_top] "r" (STACK_TOP),
|
||||
[target_addr] "r" (target),
|
||||
[exc_return] "r" (EXC_RETURN),
|
||||
[cpsr] "r" (DEFAULT_CPSR)
|
||||
: "r0", "r1", "r2");
|
||||
#endif
|
||||
|
||||
#if defined(BOOTLOADER_robotis)
|
||||
iwdg_init(IWDG_PRE_4, 10);
|
||||
#endif
|
||||
|
||||
/* Can't happen. */
|
||||
ASSERT_FAULT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOARD_HAVE_SERIALUSB
|
94
BootLoaders/Boards/stm32/cores/maple/usb_serial.h
Normal file
94
BootLoaders/Boards/stm32/cores/maple/usb_serial.h
Normal file
@ -0,0 +1,94 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Wirish USB virtual serial port (SerialUSB).
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_USB_SERIAL_H_
|
||||
#define _WIRISH_USB_SERIAL_H_
|
||||
|
||||
#include "Print.h"
|
||||
#include "boards.h"
|
||||
#include "Stream.h"
|
||||
|
||||
/**
|
||||
* @brief Virtual serial terminal.
|
||||
*/
|
||||
class USBSerial : public Stream {
|
||||
public:
|
||||
USBSerial(void);
|
||||
|
||||
void begin(void);
|
||||
|
||||
// Roger Clark. Added dummy function so that existing Arduino sketches which specify baud rate will compile.
|
||||
void begin(unsigned long);
|
||||
void begin(unsigned long, uint8_t);
|
||||
void end(void);
|
||||
|
||||
virtual int available(void);// Changed to virtual
|
||||
|
||||
size_t readBytes(char *buf, const size_t& len);
|
||||
uint32 read(uint8 * buf, uint32 len);
|
||||
// uint8 read(void);
|
||||
|
||||
// Roger Clark. added functions to support Arduino 1.0 API
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
int availableForWrite(void);
|
||||
virtual void flush(void);
|
||||
|
||||
|
||||
size_t write(uint8);
|
||||
size_t write(const char *str);
|
||||
size_t write(const uint8*, uint32);
|
||||
|
||||
uint8 getRTS();
|
||||
uint8 getDTR();
|
||||
uint8 pending();
|
||||
|
||||
/* SukkoPera: This is the Arduino way to check if an USB CDC serial
|
||||
* connection is open.
|
||||
|
||||
* Used for instance in cardinfo.ino.
|
||||
*/
|
||||
operator bool();
|
||||
|
||||
/* Old libmaple way to check for serial connection.
|
||||
*
|
||||
* Deprecated, use the above.
|
||||
*/
|
||||
uint8 isConnected() __attribute__((deprecated("Use !Serial instead"))) { return (bool) *this; }
|
||||
|
||||
protected:
|
||||
static bool _hasBegun;
|
||||
};
|
||||
|
||||
#ifdef SERIAL_USB
|
||||
extern USBSerial Serial;
|
||||
#endif
|
||||
|
||||
#endif
|
4
BootLoaders/Boards/stm32/cores/maple/wiring_private.h
Normal file
4
BootLoaders/Boards/stm32/cores/maple/wiring_private.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef WiringPrivate_h
|
||||
#define WiringPrivate_h
|
||||
|
||||
#endif
|
37
BootLoaders/Boards/stm32/cores/maple/wiring_pulse.h
Normal file
37
BootLoaders/Boards/stm32/cores/maple/wiring_pulse.h
Normal file
@ -0,0 +1,37 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2015 Roger Clark
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef _WIRISH_PULSE_H_
|
||||
#define _WIRISH_PULSE_H_
|
||||
|
||||
#include <libmaple/gpio.h>
|
||||
|
||||
uint32_t pulseIn( uint32_t ulPin, uint32_t ulState, uint32_t ulTimeout = 1000000L ) ;
|
||||
|
||||
|
||||
#endif
|
110
BootLoaders/Boards/stm32/cores/maple/wirish.h
Normal file
110
BootLoaders/Boards/stm32/cores/maple/wirish.h
Normal file
@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Main include file for the Wirish core.
|
||||
*
|
||||
* Includes most of Wirish, and (transitively or otherwise)
|
||||
* substantial pieces of libmaple proper.
|
||||
*/
|
||||
|
||||
#ifndef _WIRISH_WIRISH_H_
|
||||
#define _WIRISH_WIRISH_H_
|
||||
|
||||
/*
|
||||
* 20141030. Roger Clark
|
||||
Added the block of includes up to avr/interrupt so that stdlib functions like memcpy would be included and could be used.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <WString.h>
|
||||
#include <avr/dtostrf.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include <libmaple/stm32.h>
|
||||
|
||||
#include <boards.h>
|
||||
#include <io.h>
|
||||
#include <bit_constants.h>
|
||||
#include <pwm.h>
|
||||
#include <ext_interrupts.h>
|
||||
#include <wirish_debug.h>
|
||||
#include <wirish_math.h>
|
||||
#include <wirish_time.h>
|
||||
#include <wirish_constants.h>
|
||||
#include <wiring_pulse.h>
|
||||
|
||||
#if STM32_MCU_SERIES == STM32_SERIES_F1 /* FIXME [0.0.13?] port to F2 */
|
||||
//#include <HardwareSPI.h>
|
||||
#endif
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <HardwareTimer.h>
|
||||
#include <usb_serial.h>
|
||||
#include <wirish_types.h>
|
||||
|
||||
#include <libmaple/libmaple.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <WCharacter.h>
|
||||
#include <tone.h>
|
||||
|
||||
typedef unsigned int word;
|
||||
// typedef uint16 word;// definition from Arduino website, now appears to be incorrect for 32 bit devices
|
||||
|
||||
/* Wiring macros and bit defines */
|
||||
|
||||
#define true 0x1
|
||||
#define false 0x0
|
||||
|
||||
#define lowByte(w) ((w) & 0xFF)
|
||||
#define highByte(w) (((w) >> 8) & 0xFF)
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \
|
||||
bitClear(value, bit))
|
||||
#define bit(b) (1UL << (b))
|
||||
|
||||
// Roger Clark. Added _BV macro for AVR compatibility. As requested by @sweetlilmre and @stevestrong
|
||||
#ifndef _BV
|
||||
#define _BV(bit) (1 << (bit))
|
||||
#endif
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
|
||||
#define microsecondsToClockCycles(a) ( (a) * (F_CPU / 1000000L) )
|
||||
|
||||
#define digitalPinToInterrupt(pin) (pin)
|
||||
|
||||
#endif
|
||||
|
47
BootLoaders/Boards/stm32/cores/maple/wirish_analog.cpp
Normal file
47
BootLoaders/Boards/stm32/cores/maple/wirish_analog.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Perry Hung.
|
||||
* Copyright (c) 2011, 2012 LeafLabs, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file wirish/wirish_analog.cpp
|
||||
* @brief Wiring-style analogRead() implementation.
|
||||
*/
|
||||
|
||||
#include "io.h"
|
||||
#include <libmaple/adc.h>
|
||||
#include "boards.h"
|
||||
|
||||
/* Unlike Wiring and Arduino, this assumes that the pin's mode is set
|
||||
* to INPUT_ANALOG. That's faster, but it does require some extra work
|
||||
* on the user's part. Not too much, we think ;). */
|
||||
uint16 analogRead(uint8 pin) {
|
||||
adc_dev *dev = PIN_MAP[pin].adc_device;
|
||||
if (dev == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return adc_read(dev, PIN_MAP[pin].adc_channel);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user