push the generic_f4 branch to master
This commit is contained in:
parent
ff53626018
commit
97329efca3
|
@ -391,11 +391,11 @@ uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length
|
||||||
spi_rx_dma_enable(_currentSetting->spi_d);
|
spi_rx_dma_enable(_currentSetting->spi_d);
|
||||||
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
|
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
|
||||||
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
|
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
|
||||||
receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT));// receive buffer DMA
|
receiveBuf, dma_bit_size, (DMA_MINC_MODE));// receive buffer DMA
|
||||||
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
|
||||||
|
|
||||||
// TX
|
// TX
|
||||||
uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT);
|
uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM);
|
||||||
spi_tx_dma_enable(_currentSetting->spi_d);
|
spi_tx_dma_enable(_currentSetting->spi_d);
|
||||||
if ( transmitBuf==0 ) {
|
if ( transmitBuf==0 ) {
|
||||||
static uint8_t ff = 0XFF;
|
static uint8_t ff = 0XFF;
|
||||||
|
@ -407,13 +407,13 @@ uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length
|
||||||
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
|
||||||
|
|
||||||
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
|
||||||
|
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
|
||||||
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
|
||||||
|
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
|
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
|
||||||
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
||||||
}
|
}
|
||||||
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
|
|
||||||
|
|
||||||
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
|
@ -443,14 +443,13 @@ uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
|
||||||
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
|
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
|
||||||
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
|
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
|
||||||
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
|
||||||
|
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
|
||||||
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
|
||||||
|
|
||||||
// while (dma1_ch3_Active);
|
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
|
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
|
||||||
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
||||||
}
|
}
|
||||||
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
|
|
||||||
|
|
||||||
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
|
menu.usb_cfg=USB configuration
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
discovery_f407.name=STM32 Discovery F407
|
discovery_f407.name=STM32 Discovery F407
|
||||||
|
|
||||||
|
@ -29,6 +31,49 @@ discovery_f407.build.error_led_port=GPIOD
|
||||||
discovery_f407.build.error_led_pin=14
|
discovery_f407.build.error_led_pin=14
|
||||||
discovery_f407.build.board=STM32DiscoveryF407
|
discovery_f407.build.board=STM32DiscoveryF407
|
||||||
|
|
||||||
|
discovery_f407.menu.usb_cfg.usb_nc=USB inactive
|
||||||
|
discovery_f407.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC
|
||||||
|
discovery_f407.menu.usb_cfg.usb_serial=USB serial (CDC)
|
||||||
|
discovery_f407.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB
|
||||||
|
discovery_f407.menu.usb_cfg.usb_msc=USB Mass Storage (MSC)
|
||||||
|
discovery_f407.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC
|
||||||
|
##############################################################
|
||||||
|
generic_f407v.name=Generic STM32F407V series
|
||||||
|
|
||||||
|
generic_f407v.upload.tool=stlink_upload
|
||||||
|
generic_f407v.upload.protocol=stlink
|
||||||
|
|
||||||
|
generic_f407v.upload.file_type=bin
|
||||||
|
generic_f407v.upload.ram.maximum_size=131072
|
||||||
|
generic_f407v.upload.flash.maximum_size=514288
|
||||||
|
generic_f407v.upload.maximum_size=514288
|
||||||
|
|
||||||
|
#generic_f407v.upload.usbID=0483:3748
|
||||||
|
#generic_f407v.upload.altID=1
|
||||||
|
#generic_f407v.upload.auto_reset=true
|
||||||
|
|
||||||
|
generic_f407v.build.mcu=cortex-m4
|
||||||
|
generic_f407v.build.f_cpu=168000000L
|
||||||
|
generic_f407v.build.core=maple
|
||||||
|
generic_f407v.build.extra_flags=-mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_generic_f407v
|
||||||
|
generic_f407v.build.ldscript=ld/jtag.ld
|
||||||
|
generic_f407v.build.variant=generic_f407v
|
||||||
|
generic_f407v.build.variant_system_lib=lib_f407.a
|
||||||
|
generic_f407v.build.vect=VECT_TAB_BASE
|
||||||
|
generic_f407v.build.density=STM32_HIGH_DENSITY
|
||||||
|
generic_f407v.build.error_led_port=GPIOA
|
||||||
|
generic_f407v.build.error_led_pin=7
|
||||||
|
generic_f407v.build.board=STM32GenericF407VET6
|
||||||
|
|
||||||
|
generic_f407v.menu.usb_cfg.usb_nc=USB inactive
|
||||||
|
generic_f407v.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC
|
||||||
|
|
||||||
|
generic_f407v.menu.usb_cfg.usb_serial=USB serial (CDC)
|
||||||
|
generic_f407v.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB
|
||||||
|
|
||||||
|
generic_f407v.menu.usb_cfg.usb_msc=USB Mass Storage (MSC)
|
||||||
|
generic_f407v.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
stm32f4stamp.name=STM32F4Stamp F405
|
stm32f4stamp.name=STM32F4Stamp F405
|
||||||
|
|
||||||
|
@ -49,7 +94,7 @@ stm32f4stamp.upload.dfuse_addr=0x8000000
|
||||||
stm32f4stamp.build.mcu=cortex-m4
|
stm32f4stamp.build.mcu=cortex-m4
|
||||||
stm32f4stamp.build.f_cpu=168000000L
|
stm32f4stamp.build.f_cpu=168000000L
|
||||||
stm32f4stamp.build.core=maple
|
stm32f4stamp.build.core=maple
|
||||||
stm32f4stamp.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F2 -DSTM32F4 -DBOARD_discovery_f4
|
stm32f4stamp.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_discovery_f4
|
||||||
stm32f4stamp.build.ldscript=ld/jtag.ld
|
stm32f4stamp.build.ldscript=ld/jtag.ld
|
||||||
stm32f4stamp.build.variant=discovery_f407
|
stm32f4stamp.build.variant=discovery_f407
|
||||||
stm32f4stamp.build.variant_system_lib=lib_f407.a
|
stm32f4stamp.build.variant_system_lib=lib_f407.a
|
||||||
|
@ -59,6 +104,12 @@ stm32f4stamp.build.error_led_port=GPIOD
|
||||||
stm32f4stamp.build.error_led_pin=14
|
stm32f4stamp.build.error_led_pin=14
|
||||||
stm32f4stamp.build.board=STM32F4StampF405
|
stm32f4stamp.build.board=STM32F4StampF405
|
||||||
|
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_nc=USB inactive
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_serial=USB serial (CDC)
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_msc=USB Mass Storage (MSC)
|
||||||
|
stm32f4stamp.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC
|
||||||
##############################################################
|
##############################################################
|
||||||
netduino2plus.name=Netduino2 F405
|
netduino2plus.name=Netduino2 F405
|
||||||
|
|
||||||
|
@ -79,7 +130,7 @@ netduino2plus.upload.dfuse_addr=0x8000000
|
||||||
netduino2plus.build.mcu=cortex-m4
|
netduino2plus.build.mcu=cortex-m4
|
||||||
netduino2plus.build.f_cpu=168000000L
|
netduino2plus.build.f_cpu=168000000L
|
||||||
netduino2plus.build.core=maple
|
netduino2plus.build.core=maple
|
||||||
netduino2plus.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F2 -DSTM32F4 -DBOARD_discovery_f4 -DARDUINO_STM32F4_NETDUINO2PLUS
|
netduino2plus.build.extra_flags=-DMCU_STM32F406VG -mthumb -DSTM32_HIGH_DENSITY -DSTM32F4 -DBOARD_discovery_f4 -DARDUINO_STM32F4_NETDUINO2PLUS
|
||||||
netduino2plus.build.ldscript=ld/jtag.ld
|
netduino2plus.build.ldscript=ld/jtag.ld
|
||||||
netduino2plus.build.variant=discovery_f407
|
netduino2plus.build.variant=discovery_f407
|
||||||
netduino2plus.build.variant_system_lib=lib_f407.a
|
netduino2plus.build.variant_system_lib=lib_f407.a
|
||||||
|
@ -89,5 +140,11 @@ netduino2plus.build.error_led_port=GPIOD
|
||||||
netduino2plus.build.error_led_pin=14
|
netduino2plus.build.error_led_pin=14
|
||||||
netduino2plus.build.board=Netduino2F405
|
netduino2plus.build.board=Netduino2F405
|
||||||
|
|
||||||
|
netduino2plus.menu.usb_cfg.usb_nc=USB inactive
|
||||||
|
netduino2plus.menu.usb_cfg.usb_nc.build.cpu_flags=-DUSB_NC
|
||||||
|
netduino2plus.menu.usb_cfg.usb_serial=USB serial (CDC)
|
||||||
|
netduino2plus.menu.usb_cfg.usb_serial.build.cpu_flags=-DSERIAL_USB
|
||||||
|
netduino2plus.menu.usb_cfg.usb_msc=USB Mass Storage (MSC)
|
||||||
|
netduino2plus.menu.usb_cfg.usb_msc.build.cpu_flags=-DUSB_MSC
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef Arduino_h
|
|
||||||
#define Arduino_h
|
|
||||||
#include "WProgram.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "variant.h"
|
|
|
@ -17,8 +17,9 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef client_h
|
#ifndef _CLIENT_H_
|
||||||
#define client_h
|
#define _CLIENT_H_
|
||||||
|
|
||||||
#include "Print.h"
|
#include "Print.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "IPAddress.h"
|
#include "IPAddress.h"
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
// TODO [0.1.0] Remove deprecated pieces, pick a better API
|
// TODO [0.1.0] Remove deprecated pieces, pick a better API
|
||||||
|
|
||||||
#include "timer.h"
|
#include <libmaple/timer.h>
|
||||||
|
|
||||||
/** Timer mode. */
|
/** Timer mode. */
|
||||||
typedef timer_mode TimerMode;
|
typedef timer_mode TimerMode;
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef IPAddress_h
|
#ifndef _IPAddress_h_
|
||||||
#define IPAddress_h
|
#define _IPAddress_h_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <WString.h>
|
#include <WString.h>
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef server_h
|
#ifndef _SERVER_H_
|
||||||
#define server_h
|
#define _SERVER_H_
|
||||||
|
|
||||||
#include "Print.h"
|
#include "Print.h"
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
parsing functions based on TextFinder library by Michael Margolis
|
parsing functions based on TextFinder library by Michael Margolis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Stream_h
|
#ifndef _STREAM_H_
|
||||||
#define Stream_h
|
#define _STREAM_H_
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "Print.h"
|
#include "Print.h"
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
* bjoern@cs.stanford.edu 12/30/2008
|
* bjoern@cs.stanford.edu 12/30/2008
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef udp_h
|
#ifndef _UDP_H_
|
||||||
#define udp_h
|
#define _UDP_H_
|
||||||
|
|
||||||
#include <Stream.h>
|
#include <Stream.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
|
|
|
@ -24,7 +24,12 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "wirish.h"
|
#ifndef _WPROGRAM_H_
|
||||||
|
#define _WPROGRAM_H_
|
||||||
|
|
||||||
|
#include <wirish.h>
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,8 +19,9 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef String_class_h
|
#ifndef _WSTRING_H_
|
||||||
#define String_class_h
|
#define _WSTRING_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -225,4 +226,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
#endif // String_class_h
|
#endif // _WSTRING_H_
|
||||||
|
|
|
@ -27,4 +27,9 @@
|
||||||
/* Note: Use of this header file is deprecated. Use bit_constants.h
|
/* Note: Use of this header file is deprecated. Use bit_constants.h
|
||||||
instead. */
|
instead. */
|
||||||
|
|
||||||
|
#ifndef _BITS_H_
|
||||||
|
#define _BITS_H_
|
||||||
|
|
||||||
#include "bit_constants.h"
|
#include "bit_constants.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -33,17 +33,16 @@
|
||||||
*/
|
*/
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
|
||||||
#include "flash.h"
|
#include <libmaple/flash.h>
|
||||||
#include "rcc.h"
|
#include <libmaple/rcc.h>
|
||||||
#include "nvic.h"
|
#include <libmaple/nvic.h>
|
||||||
#include "systick.h"
|
#include <libmaple/systick.h>
|
||||||
#include "gpio.h"
|
#include <libmaple/gpio.h>
|
||||||
#include "adc.h"
|
#include <libmaple/adc.h>
|
||||||
#include "timer.h"
|
#include <libmaple/timer.h>
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#ifdef STM32F2
|
#include "usb_serial.h"
|
||||||
//#include "usbF4.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void setupFlash(void);
|
static void setupFlash(void);
|
||||||
static void setupClocks(void);
|
static void setupClocks(void);
|
||||||
|
@ -59,7 +58,7 @@ void init(void) {
|
||||||
systick_init(SYSTICK_RELOAD_VAL);
|
systick_init(SYSTICK_RELOAD_VAL);
|
||||||
gpio_init_all();
|
gpio_init_all();
|
||||||
|
|
||||||
#ifdef STM32F2
|
#ifdef STM32F4
|
||||||
rcc_clk_enable(RCC_SYSCFG);
|
rcc_clk_enable(RCC_SYSCFG);
|
||||||
#else
|
#else
|
||||||
afio_init();
|
afio_init();
|
||||||
|
@ -69,7 +68,10 @@ void init(void) {
|
||||||
setupADC();
|
setupADC();
|
||||||
setupTimers();
|
setupTimers();
|
||||||
|
|
||||||
//setupUSB();
|
#ifdef SERIAL_USB
|
||||||
|
setupUSB();
|
||||||
|
SerialUSB.begin();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* You could farm this out to the files in boards/ if e.g. it takes
|
/* You could farm this out to the files in boards/ if e.g. it takes
|
||||||
|
@ -84,11 +86,13 @@ bool boardUsesPin(uint8 pin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupFlash(void) {
|
static void setupFlash(void) {
|
||||||
|
/*
|
||||||
#ifndef STM32F2
|
#ifndef STM32F2
|
||||||
// for F2 and F4 CPUs this is done in SetupClock...(), e.g. in SetupClock168MHz()
|
// for F2 and F4 CPUs this is done in SetupClock...(), e.g. in SetupClock168MHz()
|
||||||
flash_enable_prefetch();
|
flash_enable_prefetch();
|
||||||
flash_set_latency(FLASH_WAIT_STATE_2);
|
flash_set_latency(FLASH_WAIT_STATE_2);
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -121,8 +125,8 @@ static void setupNVIC() {
|
||||||
static void adcDefaultConfig(const adc_dev* dev);
|
static void adcDefaultConfig(const adc_dev* dev);
|
||||||
|
|
||||||
static void setupADC() {
|
static void setupADC() {
|
||||||
#ifdef STM32F2
|
#ifdef STM32F4
|
||||||
setupADC_F2();
|
setupADC_F4();
|
||||||
#else
|
#else
|
||||||
rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6);
|
rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,11 +39,8 @@
|
||||||
#ifndef _BOARDS_H_
|
#ifndef _BOARDS_H_
|
||||||
#define _BOARDS_H_
|
#define _BOARDS_H_
|
||||||
|
|
||||||
#include "libmaple.h"
|
#include <wirish_types.h>
|
||||||
#include "gpio.h"
|
#include <stdbool.h>
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
#include "wirish_types.h"
|
|
||||||
|
|
||||||
/* Set of all possible pin names; not all boards have all these (note
|
/* 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
|
* that we use the Dx convention since all of the Maple's pins are
|
||||||
|
@ -55,9 +52,12 @@ enum {
|
||||||
D32, D33, D34, D35, D36, D37, D38, D39, D40, D41, D42, D43, D44, D45, D46,
|
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,
|
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,
|
D62, D63, D64, D65, D66, D67, D68, D69, D70, D71, D72, D73, D74, D75, D76,
|
||||||
|
#if 0 // not available on LQFP100 package
|
||||||
D77, D78, D79, D80, D81, D82, D83, D84, D85, D86, D87, D88, D89, D90, D91,
|
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,
|
D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105,
|
||||||
D106, D107, D108, D109, D110, D111, };
|
D106, D107, D108, D109, D110, D111,
|
||||||
|
#endif // not available on LQFP100 package
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maps each Maple pin to a corresponding stm32_pin_info.
|
* @brief Maps each Maple pin to a corresponding stm32_pin_info.
|
||||||
|
@ -115,31 +115,20 @@ extern void boardInit(void);
|
||||||
* @return true if the given pin is in boardUsedPins, and false otherwise.
|
* @return true if the given pin is in boardUsedPins, and false otherwise.
|
||||||
* @see boardUsedPins
|
* @see boardUsedPins
|
||||||
*/
|
*/
|
||||||
bool boardUsesPin(uint8 pin);
|
extern bool boardUsesPin(uint8 pin);
|
||||||
|
|
||||||
/* Include the appropriate private header from boards/: */
|
/* Include the appropriate private header from boards/: */
|
||||||
|
|
||||||
/* FIXME HACK put boards/ before these paths once IDE uses make. */
|
/* FIXME HACK put boards/ before these paths once IDE uses make. */
|
||||||
|
|
||||||
#ifdef BOARD_maple
|
#if defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1)
|
||||||
#include "maple.h"
|
|
||||||
#elif defined(BOARD_maple_native)
|
|
||||||
#include "maple_native.h"
|
|
||||||
#elif defined(BOARD_maple_mini)
|
|
||||||
#include "maple_mini.h"
|
|
||||||
#elif defined(BOARD_maple_RET6)
|
|
||||||
/*
|
|
||||||
* **NOT** MAPLE REV6. This the **Maple RET6 EDITION**, which is a
|
|
||||||
* Maple with an STM32F103RET6 (...RET6) instead of an STM32F103RBT6
|
|
||||||
* (...RBT6) on it. Maple Rev6 (as of March 2011) DOES NOT EXIST.
|
|
||||||
*/
|
|
||||||
#include "maple_RET6.h"
|
|
||||||
#elif defined(BOARD_aeroquad32) || defined(BOARD_aeroquad32f1)
|
|
||||||
#include "aeroquad32.h"
|
#include "aeroquad32.h"
|
||||||
#elif defined(BOARD_aeroquad32mini)
|
#elif defined(BOARD_aeroquad32mini)
|
||||||
#include "aeroquad32mini.h"
|
#include "aeroquad32mini.h"
|
||||||
#elif defined(BOARD_discovery_f4)
|
#elif defined(BOARD_discovery_f4)
|
||||||
#include "discovery_f4.h"
|
#include "discovery_f4.h"
|
||||||
|
#elif defined(BOARD_generic_f407v)
|
||||||
|
#include "generic_f407v.h"
|
||||||
#elif defined(BOARD_freeflight)
|
#elif defined(BOARD_freeflight)
|
||||||
#include "freeflight.h"
|
#include "freeflight.h"
|
||||||
#else
|
#else
|
||||||
|
@ -160,4 +149,12 @@ bool boardUsesPin(uint8 pin);
|
||||||
#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND
|
#define CLOCK_SPEED_MHZ CYCLES_PER_MICROSECOND
|
||||||
#define CLOCK_SPEED_HZ (CLOCK_SPEED_MHZ * 1000000UL)
|
#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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "gpio.h"
|
#include <libmaple/gpio.h>
|
||||||
#include "exti.h"
|
#include <libmaple/exti.h>
|
||||||
#include "ext_interrupts.h"
|
#include "ext_interrupts.h"
|
||||||
|
|
||||||
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode);
|
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode);
|
||||||
|
@ -51,7 +51,7 @@ void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) {
|
||||||
|
|
||||||
exti_trigger_mode outMode = exti_out_mode(mode);
|
exti_trigger_mode outMode = exti_out_mode(mode);
|
||||||
|
|
||||||
exti_attach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit),
|
exti_attach_interrupt((afio_exti_num)(pin&0x0F),
|
||||||
gpio_exti_port(PIN_MAP[pin].gpio_device),
|
gpio_exti_port(PIN_MAP[pin].gpio_device),
|
||||||
handler,
|
handler,
|
||||||
outMode);
|
outMode);
|
||||||
|
@ -66,7 +66,7 @@ void detachInterrupt(uint8 pin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exti_detach_interrupt((afio_exti_num)(PIN_MAP[pin].gpio_bit));
|
exti_detach_interrupt((afio_exti_num)(pin&0x0F));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) {
|
static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) {
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
#ifndef _EXT_INTERRUPTS_H_
|
||||||
#include "nvic.h"
|
#define _EXT_INTERRUPTS_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file ext_interrupts.h
|
* @file ext_interrupts.h
|
||||||
|
@ -33,8 +33,9 @@
|
||||||
* @brief Wiring-like external interrupt prototypes and types.
|
* @brief Wiring-like external interrupt prototypes and types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _EXT_INTERRUPTS_H_
|
#include <libmaple/libmaple_types.h>
|
||||||
#define _EXT_INTERRUPTS_H_
|
#include <libmaple/nvic.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The kind of transition on an external pin which should trigger an
|
* The kind of transition on an external pin which should trigger an
|
||||||
|
|
|
@ -33,8 +33,9 @@
|
||||||
#ifndef _IO_H_
|
#ifndef _IO_H_
|
||||||
#define _IO_H_
|
#define _IO_H_
|
||||||
|
|
||||||
#include "gpio.h"
|
#include <inttypes.h>
|
||||||
#include "adc.h"
|
#include <libmaple/gpio.h>
|
||||||
|
#include <libmaple/adc.h>
|
||||||
|
|
||||||
#include "wirish_time.h"
|
#include "wirish_time.h"
|
||||||
|
|
||||||
|
@ -179,9 +180,11 @@ static inline void toggleLED() {
|
||||||
* accomplished portably over all LeafLabs boards by calling
|
* accomplished portably over all LeafLabs boards by calling
|
||||||
* pinMode(BOARD_BUTTON_PIN, INPUT).
|
* pinMode(BOARD_BUTTON_PIN, INPUT).
|
||||||
*
|
*
|
||||||
|
* @param button - one of available on-board buttons (up to 3 for generic F4)
|
||||||
|
*
|
||||||
* @see pinMode()
|
* @see pinMode()
|
||||||
*/
|
*/
|
||||||
uint8 isButtonPressed();
|
uint8 isButtonPressed(uint8_t button);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait until the button is pressed and released, timing out if no
|
* Wait until the button is pressed and released, timing out if no
|
||||||
|
@ -195,12 +198,14 @@ uint8 isButtonPressed();
|
||||||
* button is pressed. If timeout_millis is left out (or 0), wait
|
* button is pressed. If timeout_millis is left out (or 0), wait
|
||||||
* forever.
|
* forever.
|
||||||
*
|
*
|
||||||
|
* @param button - one of available on-board buttons (up to 3 for generic F4)
|
||||||
|
*
|
||||||
* @return true, if the button was pressed; false, if the timeout was
|
* @return true, if the button was pressed; false, if the timeout was
|
||||||
* reached.
|
* reached.
|
||||||
*
|
*
|
||||||
* @see pinMode()
|
* @see pinMode()
|
||||||
*/
|
*/
|
||||||
uint8 waitForButtonPress(uint32 timeout_millis=0);
|
uint8 waitForButtonPress(uint8_t button, uint32 timeout_millis=0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift out a byte of data, one bit at a time.
|
* Shift out a byte of data, one bit at a time.
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ITOA_
|
#ifndef _ITOA_H_
|
||||||
#define _ITOA_
|
#define _ITOA_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
|
|
|
@ -1,424 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
|
||||||
* @brief Wirish SPI implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "HardwareSPI.h"
|
|
||||||
|
|
||||||
#include "timer.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "rcc.h"
|
|
||||||
|
|
||||||
#include "wirish.h"
|
|
||||||
#include "boards.h"
|
|
||||||
|
|
||||||
struct spi_pins {
|
|
||||||
uint8 nss;
|
|
||||||
uint8 sck;
|
|
||||||
uint8 miso;
|
|
||||||
uint8 mosi;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const spi_pins* dev_to_spi_pins(spi_dev *dev);
|
|
||||||
|
|
||||||
static void enable_device(spi_dev *dev,
|
|
||||||
bool as_master,
|
|
||||||
SPIFrequency frequency,
|
|
||||||
spi_cfg_flag endianness,
|
|
||||||
spi_mode mode);
|
|
||||||
|
|
||||||
static const spi_pins board_spi_pins[] __FLASH__ = {
|
|
||||||
{BOARD_SPI1_NSS_PIN,
|
|
||||||
BOARD_SPI1_SCK_PIN,
|
|
||||||
BOARD_SPI1_MISO_PIN,
|
|
||||||
BOARD_SPI1_MOSI_PIN},
|
|
||||||
#ifdef BOARD_SPI2_NSS_PIN
|
|
||||||
{BOARD_SPI2_NSS_PIN,
|
|
||||||
BOARD_SPI2_SCK_PIN,
|
|
||||||
BOARD_SPI2_MISO_PIN,
|
|
||||||
BOARD_SPI2_MOSI_PIN},
|
|
||||||
#endif
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
{BOARD_SPI3B_NSS_PIN,
|
|
||||||
BOARD_SPI3B_SCK_PIN,
|
|
||||||
BOARD_SPI3B_MISO_PIN,
|
|
||||||
BOARD_SPI3B_MOSI_PIN},
|
|
||||||
#endif
|
|
||||||
#ifdef STM32F4
|
|
||||||
{BOARD_SPI3B_NSS_PIN,
|
|
||||||
BOARD_SPI3B_SCK_PIN,
|
|
||||||
BOARD_SPI3B_MISO_PIN,
|
|
||||||
BOARD_SPI3B_MOSI_PIN},
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
|
|
||||||
HardwareSPI::HardwareSPI(uint32 spi_num) {
|
|
||||||
switch (spi_num) {
|
|
||||||
case 1:
|
|
||||||
this->spi_d = SPI1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this->spi_d = SPI2;
|
|
||||||
break;
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
case 3:
|
|
||||||
this->spi_d = SPI3;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef STM32F4
|
|
||||||
// case 4:
|
|
||||||
// this->spi_d = SPI4;
|
|
||||||
// break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up/tear down
|
|
||||||
*/
|
|
||||||
|
|
||||||
void HardwareSPI::begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode) {
|
|
||||||
if (mode >= 4) {
|
|
||||||
ASSERT(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
|
|
||||||
spi_mode m = (spi_mode)mode;
|
|
||||||
enable_device(this->spi_d, true, frequency, end, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::begin(void) {
|
|
||||||
this->begin(SPI_1_125MHZ, MSBFIRST, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::beginSlave(uint32 bitOrder, uint32 mode) {
|
|
||||||
if (mode >= 4) {
|
|
||||||
ASSERT(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
|
|
||||||
spi_mode m = (spi_mode)mode;
|
|
||||||
enable_device(this->spi_d, false, (SPIFrequency)0, end, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::beginSlave(void) {
|
|
||||||
this->beginSlave(MSBFIRST, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void HardwareSPI::beginTransaction(uint8_t pin, SPISettings settings)
|
|
||||||
{
|
|
||||||
// this->begin(settings.clock, settings.bitOrder, settings.dataMode);
|
|
||||||
this->begin(SPI_1_125MHZ, settings.bitOrder, settings.dataMode);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void HardwareSPI::end(void) {
|
|
||||||
if (!spi_is_enabled(this->spi_d)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Follows RM0008's sequence for disabling a SPI in master/slave
|
|
||||||
// full duplex mode.
|
|
||||||
while (spi_is_rx_nonempty(this->spi_d)) {
|
|
||||||
// FIXME [0.1.0] remove this once you have an interrupt based driver
|
|
||||||
volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d);
|
|
||||||
}
|
|
||||||
while (!spi_is_tx_empty(this->spi_d))
|
|
||||||
;
|
|
||||||
while (spi_is_busy(this->spi_d))
|
|
||||||
;
|
|
||||||
spi_peripheral_disable(this->spi_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* I/O
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint8 HardwareSPI::read(void) {
|
|
||||||
uint8 buf[1];
|
|
||||||
this->read(buf, 1);
|
|
||||||
return buf[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::read(uint8 *buf, uint32 len) {
|
|
||||||
uint32 rxed = 0;
|
|
||||||
while (rxed < len) {
|
|
||||||
while (!spi_is_rx_nonempty(this->spi_d))
|
|
||||||
;
|
|
||||||
buf[rxed++] = (uint8)spi_rx_reg(this->spi_d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void HardwareSPI::readMaster(uint8 *buf, uint32 len) {
|
|
||||||
uint32 rxed = 0;
|
|
||||||
while (rxed < len) {
|
|
||||||
spi_tx_reg(this->spi_d, 0xff);
|
|
||||||
while (!spi_is_rx_nonempty(this->spi_d))
|
|
||||||
;
|
|
||||||
buf[rxed++] = (uint8)spi_rx_reg(this->spi_d);
|
|
||||||
buf[rxed++] = this->spi_d->regs->DR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void HardwareSPI::readMaster(uint8 *buf, uint32 len) {
|
|
||||||
spi_reg_map *r = this->spi_d->regs;
|
|
||||||
uint32 rxed = 0;
|
|
||||||
while (rxed < len) {
|
|
||||||
r->DR = 0xff;
|
|
||||||
while (!(r->SR & SPI_SR_RXNE))
|
|
||||||
;
|
|
||||||
buf[rxed++] = r->DR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HardwareSPI::waitReady() {
|
|
||||||
while (!spi_is_rx_nonempty(this->spi_d))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::write(uint8 byte) {
|
|
||||||
this->write(&byte, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareSPI::write(const uint8 *data, uint32 length) {
|
|
||||||
uint32 txed = 0;
|
|
||||||
while (txed < length) {
|
|
||||||
txed += spi_tx(this->spi_d, data + txed, length - txed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 HardwareSPI::transfer(uint8 byte) {
|
|
||||||
this->write(byte);
|
|
||||||
return this->read();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pin accessors
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint8 HardwareSPI::misoPin(void) {
|
|
||||||
return dev_to_spi_pins(this->spi_d)->miso;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 HardwareSPI::mosiPin(void) {
|
|
||||||
return dev_to_spi_pins(this->spi_d)->mosi;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 HardwareSPI::sckPin(void) {
|
|
||||||
return dev_to_spi_pins(this->spi_d)->sck;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 HardwareSPI::nssPin(void) {
|
|
||||||
return dev_to_spi_pins(this->spi_d)->nss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deprecated functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint8 HardwareSPI::send(uint8 data) {
|
|
||||||
uint8 buf[] = {data};
|
|
||||||
return this->send(buf, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
uint8 HardwareSPI::send(const uint8 *buf, uint32 len) {
|
|
||||||
uint32 txed = 0;
|
|
||||||
uint8 ret = 0;
|
|
||||||
while (txed < len) {
|
|
||||||
this->write(buf[txed++]);
|
|
||||||
ret = this->read();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// this does not work for an unknown reason
|
|
||||||
uint8 HardwareSPI::send(const uint8 *buf, uint32 len) {
|
|
||||||
volatile uint32 *dr = &(this->spi_d->regs->DR);
|
|
||||||
volatile uint32 *sr = &(this->spi_d->regs->SR);
|
|
||||||
uint32 txed = 0;
|
|
||||||
uint32 rx=0;
|
|
||||||
while (txed < len) {
|
|
||||||
//while (!(*sr & SPI_SR_TXE))
|
|
||||||
// ;
|
|
||||||
//*dr = buf[txed++];
|
|
||||||
this->write(buf[txed++]);
|
|
||||||
|
|
||||||
while (!(*sr & SPI_SR_RXNE))
|
|
||||||
;
|
|
||||||
rx = *dr;
|
|
||||||
//rx = this->read();
|
|
||||||
}
|
|
||||||
|
|
||||||
return rx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8 HardwareSPI::recv(void) {
|
|
||||||
return this->read();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Auxiliary functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void configure_gpios(spi_dev *dev, bool as_master);
|
|
||||||
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq);
|
|
||||||
|
|
||||||
static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
|
|
||||||
switch (dev->clk_id) {
|
|
||||||
case RCC_SPI1: return board_spi_pins;
|
|
||||||
case RCC_SPI2: return board_spi_pins + 1;
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
case RCC_SPI3: return board_spi_pins + 2;
|
|
||||||
#endif
|
|
||||||
#ifdef STM32F4
|
|
||||||
case RCC_SPI4: return board_spi_pins + 3;
|
|
||||||
#endif
|
|
||||||
default: return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enables the device in master or slave full duplex mode. If you
|
|
||||||
* change this code, you must ensure that appropriate changes are made
|
|
||||||
* to HardwareSPI::end(). */
|
|
||||||
static void enable_device(spi_dev *dev,
|
|
||||||
bool as_master,
|
|
||||||
SPIFrequency freq,
|
|
||||||
spi_cfg_flag endianness,
|
|
||||||
spi_mode mode) {
|
|
||||||
spi_baud_rate baud = determine_baud_rate(dev, freq);
|
|
||||||
uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE |
|
|
||||||
(as_master ? SPI_SOFT_SS : 0));
|
|
||||||
|
|
||||||
spi_init(dev);
|
|
||||||
configure_gpios(dev, as_master);
|
|
||||||
if (as_master) {
|
|
||||||
spi_master_enable(dev, baud, mode, cfg_flags);
|
|
||||||
} else {
|
|
||||||
spi_slave_enable(dev, mode, cfg_flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disable_pwm(const stm32_pin_info *i) {
|
|
||||||
if (i->timer_device) {
|
|
||||||
timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void configure_gpios(spi_dev *dev, bool as_master) {
|
|
||||||
const spi_pins *pins = dev_to_spi_pins(dev);
|
|
||||||
|
|
||||||
if (!pins) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const stm32_pin_info *nssi = (pins->nss >= 0) ? &PIN_MAP[pins->nss] : NULL;
|
|
||||||
const stm32_pin_info *scki = &PIN_MAP[pins->sck];
|
|
||||||
const stm32_pin_info *misoi = &PIN_MAP[pins->miso];
|
|
||||||
const stm32_pin_info *mosii = &PIN_MAP[pins->mosi];
|
|
||||||
|
|
||||||
if(nssi) {
|
|
||||||
disable_pwm(nssi);
|
|
||||||
}
|
|
||||||
disable_pwm(scki);
|
|
||||||
disable_pwm(misoi);
|
|
||||||
disable_pwm(mosii);
|
|
||||||
|
|
||||||
#ifdef STM32F4
|
|
||||||
if(dev->clk_id <= RCC_SPI2) {
|
|
||||||
if(nssi) {
|
|
||||||
if(!as_master) {
|
|
||||||
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 5);
|
|
||||||
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 5);
|
|
||||||
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 5);
|
|
||||||
} else {
|
|
||||||
if(nssi) {
|
|
||||||
if(!as_master) {
|
|
||||||
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 6);
|
|
||||||
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 6);
|
|
||||||
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 6);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(nssi) {
|
|
||||||
spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit,
|
|
||||||
scki->gpio_device, scki->gpio_bit,
|
|
||||||
misoi->gpio_device, misoi->gpio_bit,
|
|
||||||
mosii->gpio_device, mosii->gpio_bit);
|
|
||||||
} else {
|
|
||||||
spi_config_gpios(dev, as_master, NULL, -1,
|
|
||||||
scki->gpio_device, scki->gpio_bit,
|
|
||||||
misoi->gpio_device, misoi->gpio_bit,
|
|
||||||
mosii->gpio_device, mosii->gpio_bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = {
|
|
||||||
SPI_BAUD_PCLK_DIV_2,
|
|
||||||
SPI_BAUD_PCLK_DIV_4,
|
|
||||||
SPI_BAUD_PCLK_DIV_8,
|
|
||||||
SPI_BAUD_PCLK_DIV_16,
|
|
||||||
SPI_BAUD_PCLK_DIV_32,
|
|
||||||
SPI_BAUD_PCLK_DIV_64,
|
|
||||||
SPI_BAUD_PCLK_DIV_128,
|
|
||||||
SPI_BAUD_PCLK_DIV_256,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: This assumes you're on a LeafLabs-style board
|
|
||||||
* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
|
|
||||||
*/
|
|
||||||
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) {
|
|
||||||
if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) {
|
|
||||||
/* APB2 peripherals are too fast for 140.625 KHz */
|
|
||||||
ASSERT(0);
|
|
||||||
return (spi_baud_rate)~0;
|
|
||||||
}
|
|
||||||
return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ?
|
|
||||||
baud_rates[freq + 1] :
|
|
||||||
baud_rates[freq]);
|
|
||||||
}
|
|
|
@ -1,279 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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 HardwareSPI.h
|
|
||||||
* @brief High-level SPI interface
|
|
||||||
*
|
|
||||||
* This is a "bare essentials" polling driver for now.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO [0.1.0] Remove deprecated methods. */
|
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
#include "spi.h"
|
|
||||||
|
|
||||||
#include "boards.h"
|
|
||||||
#include "wirish.h"
|
|
||||||
|
|
||||||
#ifndef _HARDWARESPI_H_
|
|
||||||
#define _HARDWARESPI_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines the possible SPI communication speeds.
|
|
||||||
*/
|
|
||||||
typedef enum SPIFrequency {
|
|
||||||
SPI_18MHZ = 0, /**< 18 MHz */
|
|
||||||
SPI_9MHZ = 1, /**< 9 MHz */
|
|
||||||
SPI_4_5MHZ = 2, /**< 4.5 MHz */
|
|
||||||
SPI_2_25MHZ = 3, /**< 2.25 MHz */
|
|
||||||
SPI_1_125MHZ = 4, /**< 1.125 MHz */
|
|
||||||
SPI_562_500KHZ = 5, /**< 562.500 KHz */
|
|
||||||
SPI_281_250KHZ = 6, /**< 281.250 KHz */
|
|
||||||
SPI_140_625KHZ = 7, /**< 140.625 KHz */
|
|
||||||
} SPIFrequency;
|
|
||||||
|
|
||||||
#define MAX_SPI_FREQS 8
|
|
||||||
|
|
||||||
#if CYCLES_PER_MICROSECOND != 72
|
|
||||||
/* TODO [0.2.0?] something smarter than this */
|
|
||||||
//#warning "Unexpected clock speed; SPI frequency calculation will be incorrect"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//#define BOARD_SPI_DEFAULT_SS PC13
|
|
||||||
#define BOARD_SPI_DEFAULT_SS PB0
|
|
||||||
#define SPI_MODE0 SPI_MODE_0
|
|
||||||
#define SPI_MODE1 SPI_MODE_1
|
|
||||||
#define SPI_MODE2 SPI_MODE_2
|
|
||||||
#define SPI_MODE3 SPI_MODE_3
|
|
||||||
|
|
||||||
/*
|
|
||||||
class SPISettings {
|
|
||||||
public:
|
|
||||||
SPISettings(uint32 clock, BitOrder bitOrder, uint8 dataMode) {
|
|
||||||
if (__builtin_constant_p(clock)) {
|
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
|
||||||
} else {
|
|
||||||
init_MightInline(clock, bitOrder, dataMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
|
|
||||||
private:
|
|
||||||
void init_MightInline(uint32 clock, BitOrder bitOrder, uint8 dataMode) {
|
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
|
||||||
}
|
|
||||||
void init_AlwaysInline(uint32 clock, BitOrder bitOrder, uint8 dataMode) __attribute__((__always_inline__)) {
|
|
||||||
this->clock = clock;
|
|
||||||
this->bitOrder = bitOrder;
|
|
||||||
this->dataMode = dataMode;
|
|
||||||
}
|
|
||||||
uint32 clock;
|
|
||||||
BitOrder bitOrder;
|
|
||||||
uint8 dataMode;
|
|
||||||
friend class HardwareSPI;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wirish SPI interface.
|
|
||||||
*
|
|
||||||
* This implementation uses software slave management, so the caller
|
|
||||||
* is responsible for controlling the slave select line.
|
|
||||||
*/
|
|
||||||
class HardwareSPI {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @param spiPortNumber Number of the SPI port to manage.
|
|
||||||
*/
|
|
||||||
HardwareSPI(uint32 spiPortNumber);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up/tear down
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Turn on a SPI port and set its GPIO pin modes for use as master.
|
|
||||||
*
|
|
||||||
* SPI port is enabled in full duplex mode, with software slave management.
|
|
||||||
*
|
|
||||||
* @param frequency Communication frequency
|
|
||||||
* @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian)
|
|
||||||
* @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1,
|
|
||||||
* SPI_MODE_2, and SPI_MODE_3.
|
|
||||||
*/
|
|
||||||
void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
|
|
||||||
*/
|
|
||||||
void begin(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Turn on a SPI port and set its GPIO pin modes for use as a slave.
|
|
||||||
*
|
|
||||||
* SPI port is enabled in full duplex mode, with software slave management.
|
|
||||||
*
|
|
||||||
* @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian)
|
|
||||||
* @param mode SPI mode to use
|
|
||||||
*/
|
|
||||||
void beginSlave(uint32 bitOrder, uint32 mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Equivalent to beginSlave(MSBFIRST, 0).
|
|
||||||
*/
|
|
||||||
void beginSlave(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disables the SPI port, but leaves its GPIO pin modes unchanged.
|
|
||||||
*/
|
|
||||||
void end(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* I/O
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the next unread byte.
|
|
||||||
*
|
|
||||||
* If there is no unread byte waiting, this function will block
|
|
||||||
* until one is received.
|
|
||||||
*/
|
|
||||||
uint8 read(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read length bytes, storing them into buffer.
|
|
||||||
* @param buffer Buffer to store received bytes into.
|
|
||||||
* @param length Number of bytes to store in buffer. This
|
|
||||||
* function will block until the desired number of
|
|
||||||
* bytes have been read.
|
|
||||||
*/
|
|
||||||
void read(uint8 *buffer, uint32 length);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read length bytes, storing them into buffer.
|
|
||||||
* @param buffer Buffer to store received bytes into.
|
|
||||||
* @param length Number of bytes to store in buffer. This
|
|
||||||
* function will block until the desired number of
|
|
||||||
* bytes have been read.
|
|
||||||
*/
|
|
||||||
void readMaster(uint8 *buffer, uint32 length);
|
|
||||||
|
|
||||||
|
|
||||||
void waitReady();
|
|
||||||
/**
|
|
||||||
* @brief Transmit a byte.
|
|
||||||
* @param data Byte to transmit.
|
|
||||||
*/
|
|
||||||
void write(uint8 data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit multiple bytes.
|
|
||||||
* @param buffer Bytes to transmit.
|
|
||||||
* @param length Number of bytes in buffer to transmit.
|
|
||||||
*/
|
|
||||||
void write(const uint8 *buffer, uint32 length);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit a byte, then return the next unread byte.
|
|
||||||
*
|
|
||||||
* This function transmits before receiving.
|
|
||||||
*
|
|
||||||
* @param data Byte to transmit.
|
|
||||||
* @return Next unread byte.
|
|
||||||
*/
|
|
||||||
uint8 transfer(uint8 data);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pin accessors
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the number of the MISO (master in, slave out) pin
|
|
||||||
*/
|
|
||||||
uint8 misoPin(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the number of the MOSI (master out, slave in) pin
|
|
||||||
*/
|
|
||||||
uint8 mosiPin(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the number of the SCK (serial clock) pin
|
|
||||||
*/
|
|
||||||
uint8 sckPin(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the number of the NSS (slave select) pin
|
|
||||||
*/
|
|
||||||
uint8 nssPin(void);
|
|
||||||
|
|
||||||
/* -- The following methods are deprecated --------------------------- */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deprecated.
|
|
||||||
*
|
|
||||||
* Use HardwareSPI::transfer() instead.
|
|
||||||
*
|
|
||||||
* @see HardwareSPI::transfer()
|
|
||||||
*/
|
|
||||||
uint8 send(uint8 data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deprecated.
|
|
||||||
*
|
|
||||||
* Use HardwareSPI::write() in combination with
|
|
||||||
* HardwareSPI::read() (or HardwareSPI::transfer()) instead.
|
|
||||||
*
|
|
||||||
* @see HardwareSPI::write()
|
|
||||||
* @see HardwareSPI::read()
|
|
||||||
* @see HardwareSPI::transfer()
|
|
||||||
*/
|
|
||||||
uint8 send(const uint8 *data, uint32 length);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deprecated.
|
|
||||||
*
|
|
||||||
* Use HardwareSPI::read() instead.
|
|
||||||
*
|
|
||||||
* @see HardwareSPI::read()
|
|
||||||
*/
|
|
||||||
uint8 recv(void);
|
|
||||||
|
|
||||||
// void beginTransaction(SPISettings settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); }
|
|
||||||
// void beginTransaction(uint8 pin, SPISettings settings);
|
|
||||||
void endTransaction(void) { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
spi_dev *spi_d;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern HardwareSPI SPI;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -56,19 +56,19 @@
|
||||||
#define RX5 BOARD_UART5_RX_PIN
|
#define RX5 BOARD_UART5_RX_PIN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HardwareSerial Serial(USART1, TX1, RX1);
|
HardwareSerial Serial1(USART1, TX1, RX1);
|
||||||
|
|
||||||
#ifdef TX2
|
#ifdef TX2
|
||||||
HardwareSerial Serial1(USART2, TX2, RX2);
|
HardwareSerial Serial2(USART2, TX2, RX2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TX3
|
#ifdef TX3
|
||||||
HardwareSerial Serial2(USART3, TX3, RX3);
|
HardwareSerial Serial3(USART3, TX3, RX3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6)
|
#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6)
|
||||||
HardwareSerial Serial3(UART4, TX4, RX4);
|
HardwareSerial Serial4(UART4, TX4, RX4);
|
||||||
HardwareSerial Serial4(UART5, TX5, RX5);
|
HardwareSerial Serial5(UART5, TX5, RX5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HardwareSerial::HardwareSerial(usart_dev *usart_device,
|
HardwareSerial::HardwareSerial(usart_dev *usart_device,
|
||||||
|
@ -90,25 +90,23 @@ void HardwareSerial::begin(uint32 baud) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stm32_pin_info *txi = &PIN_MAP[tx_pin];
|
#ifdef STM32F4
|
||||||
const stm32_pin_info *rxi = &PIN_MAP[rx_pin];
|
|
||||||
#ifdef STM32F2
|
|
||||||
// int af = 7<<8;
|
// int af = 7<<8;
|
||||||
if (usart_device == UART4 || usart_device == UART5) {
|
if (usart_device == UART4 || usart_device == UART5) {
|
||||||
gpio_set_af_mode(txi->gpio_device, txi->gpio_bit, 8);
|
gpio_set_af_mode(tx_pin, 8);
|
||||||
gpio_set_af_mode(rxi->gpio_device, rxi->gpio_bit, 8);
|
gpio_set_af_mode(rx_pin, 8);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gpio_set_af_mode(txi->gpio_device, txi->gpio_bit, 7);
|
gpio_set_af_mode(tx_pin, 7);
|
||||||
gpio_set_af_mode(rxi->gpio_device, rxi->gpio_bit, 7);
|
gpio_set_af_mode(rx_pin, 7);
|
||||||
}
|
}
|
||||||
gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_AF_OUTPUT_PP | GPIO_PUPD_INPUT_PU | 0x700));
|
gpio_set_mode(tx_pin, (gpio_pin_mode)(GPIO_AF_OUTPUT_PP | GPIO_PUPD_INPUT_PU | 0x700));
|
||||||
gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_PUPD_INPUT_PU | 0x700));
|
gpio_set_mode(rx_pin, (gpio_pin_mode)(GPIO_MODE_AF | GPIO_PUPD_INPUT_PU | 0x700));
|
||||||
//gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU));
|
//gpio_set_mode(txi->gpio_device, txi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU));
|
||||||
//gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU));
|
//gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, (gpio_pin_mode)(GPIO_PUPD_INPUT_PU));
|
||||||
#else
|
#else
|
||||||
gpio_set_mode(txi->gpio_device, txi->gpio_bit, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(tx_pin, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, GPIO_INPUT_FLOATING);
|
gpio_set_mode(rx_pin, GPIO_INPUT_FLOATING);
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
if (txi->timer_device != NULL) {
|
if (txi->timer_device != NULL) {
|
||||||
|
|
|
@ -75,12 +75,12 @@ private:
|
||||||
uint8 rx_pin;
|
uint8 rx_pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HardwareSerial Serial;
|
|
||||||
extern HardwareSerial Serial1;
|
extern HardwareSerial Serial1;
|
||||||
extern HardwareSerial Serial2;
|
extern HardwareSerial Serial2;
|
||||||
#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6)
|
#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6)
|
||||||
extern HardwareSerial Serial3;
|
extern HardwareSerial Serial3;
|
||||||
extern HardwareSerial Serial4;
|
extern HardwareSerial Serial4;
|
||||||
|
extern HardwareSerial Serial5;
|
||||||
#endif
|
#endif
|
||||||
extern HardwareSerial &SerialDebug;
|
extern HardwareSerial &SerialDebug;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,27 +41,24 @@
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
|
||||||
static adc_dev adc1 = {
|
/** ADC1 device. */
|
||||||
|
const adc_dev ADC1 = {
|
||||||
.regs = ADC1_BASE,
|
.regs = ADC1_BASE,
|
||||||
.clk_id = RCC_ADC1
|
.clk_id = RCC_ADC1
|
||||||
};
|
};
|
||||||
/** ADC1 device. */
|
|
||||||
const adc_dev *ADC1 = &adc1;
|
|
||||||
|
|
||||||
static adc_dev adc2 = {
|
/** ADC2 device. */
|
||||||
|
const adc_dev ADC2 = {
|
||||||
.regs = ADC2_BASE,
|
.regs = ADC2_BASE,
|
||||||
.clk_id = RCC_ADC2
|
.clk_id = RCC_ADC2
|
||||||
};
|
};
|
||||||
/** ADC2 device. */
|
|
||||||
const adc_dev *ADC2 = &adc2;
|
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
adc_dev adc3 = {
|
/** ADC3 device. */
|
||||||
|
const adc_dev ADC3 = {
|
||||||
.regs = ADC3_BASE,
|
.regs = ADC3_BASE,
|
||||||
.clk_id = RCC_ADC3
|
.clk_id = RCC_ADC3
|
||||||
};
|
};
|
||||||
/** ADC3 device. */
|
|
||||||
const adc_dev *ADC3 = &adc3;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +71,7 @@ const adc_dev *ADC3 = &adc3;
|
||||||
*/
|
*/
|
||||||
void adc_init(const adc_dev *dev) {
|
void adc_init(const adc_dev *dev) {
|
||||||
rcc_clk_enable(dev->clk_id);
|
rcc_clk_enable(dev->clk_id);
|
||||||
#ifdef STM32F2
|
#ifdef STM32F4
|
||||||
if(dev->clk_id == RCC_ADC1) {
|
if(dev->clk_id == RCC_ADC1) {
|
||||||
rcc_reset_dev(dev->clk_id);
|
rcc_reset_dev(dev->clk_id);
|
||||||
}
|
}
|
||||||
|
@ -101,10 +98,10 @@ void adc_set_extsel(const adc_dev *dev, adc_extsel_event event) {
|
||||||
* @param fn Function to call on each ADC device.
|
* @param fn Function to call on each ADC device.
|
||||||
*/
|
*/
|
||||||
void adc_foreach(void (*fn)(const adc_dev*)) {
|
void adc_foreach(void (*fn)(const adc_dev*)) {
|
||||||
fn(ADC1);
|
fn(&ADC1);
|
||||||
fn(ADC2);
|
fn(&ADC2);
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
fn(ADC3);
|
fn(&ADC3);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +133,9 @@ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) {
|
||||||
* @brief Calibrate an ADC peripheral
|
* @brief Calibrate an ADC peripheral
|
||||||
* @param dev adc device
|
* @param dev adc device
|
||||||
*/
|
*/
|
||||||
void adc_calibrate(const adc_dev *dev) {
|
void adc_calibrate(const adc_dev *dev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
#ifndef STM32F2
|
#ifndef STM32F2
|
||||||
__io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3);
|
__io uint32 *rstcal_bit = bb_perip(&(dev->regs->CR2), 3);
|
||||||
__io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2);
|
__io uint32 *cal_bit = bb_perip(&(dev->regs->CR2), 2);
|
||||||
|
@ -149,6 +148,7 @@ void adc_calibrate(const adc_dev *dev) {
|
||||||
while (*cal_bit)
|
while (*cal_bit)
|
||||||
;
|
;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,8 +171,8 @@ uint16 adc_read(const adc_dev *dev, uint8 channel) {
|
||||||
return (uint16)(regs->DR & ADC_DR_DATA);
|
return (uint16)(regs->DR & ADC_DR_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupADC_F2() {
|
void setupADC_F4(void)
|
||||||
#ifdef STM32F2
|
{
|
||||||
uint32 tmpreg1 = 0;
|
uint32 tmpreg1 = 0;
|
||||||
|
|
||||||
tmpreg1 = ADC_COMMON->CCR;
|
tmpreg1 = ADC_COMMON->CCR;
|
||||||
|
@ -196,5 +196,4 @@ void setupADC_F2() {
|
||||||
|
|
||||||
/* Write to ADC CCR */
|
/* Write to ADC CCR */
|
||||||
ADC_COMMON->CCR = tmpreg1;
|
ADC_COMMON->CCR = tmpreg1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,17 +42,15 @@ extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef STM32F2
|
typedef struct
|
||||||
typedef struct
|
{
|
||||||
{
|
__io uint32 CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */
|
||||||
__io uint32 CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */
|
__io uint32 CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */
|
||||||
__io uint32 CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */
|
__io uint32 CDR; /*!< ADC common regular data register for dual
|
||||||
__io uint32 CDR; /*!< ADC common regular data register for dual
|
AND triple modes, Address offset: ADC1 base address + 0x308 */
|
||||||
AND triple modes, Address offset: ADC1 base address + 0x308 */
|
} ADC_Common_TypeDef;
|
||||||
} ADC_Common_TypeDef;
|
|
||||||
#define ADC_COMMON ((ADC_Common_TypeDef *) 0x40012300)
|
#define ADC_COMMON ((ADC_Common_TypeDef *) 0x40012300)
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** ADC register map type. */
|
/** ADC register map type. */
|
||||||
typedef struct adc_reg_map {
|
typedef struct adc_reg_map {
|
||||||
|
@ -84,33 +82,22 @@ typedef struct adc_dev {
|
||||||
rcc_clk_id clk_id; /**< RCC clock information */
|
rcc_clk_id clk_id; /**< RCC clock information */
|
||||||
} adc_dev;
|
} adc_dev;
|
||||||
|
|
||||||
extern const adc_dev *ADC1;
|
extern const adc_dev ADC1;
|
||||||
extern const adc_dev *ADC2;
|
extern const adc_dev ADC2;
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
extern const adc_dev *ADC3;
|
extern const adc_dev ADC3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register map base pointers
|
* Register map base pointers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STM32F2
|
/** ADC1 register map base pointer. */
|
||||||
/** ADC1 register map base pointer. */
|
#define ADC1_BASE ((struct adc_reg_map*)0x40012000)
|
||||||
#define ADC1_BASE ((struct adc_reg_map*)0x40012000)
|
/** ADC2 register map base pointer. */
|
||||||
/** ADC2 register map base pointer. */
|
#define ADC2_BASE ((struct adc_reg_map*)0x40012100)
|
||||||
#define ADC2_BASE ((struct adc_reg_map*)0x40012100)
|
/** ADC3 register map base pointer. */
|
||||||
/** ADC3 register map base pointer. */
|
#define ADC3_BASE ((struct adc_reg_map*)0x40012200)
|
||||||
#define ADC3_BASE ((struct adc_reg_map*)0x40012200)
|
|
||||||
#else
|
|
||||||
/** ADC1 register map base pointer. */
|
|
||||||
#define ADC1_BASE ((struct adc_reg_map*)0x40012400)
|
|
||||||
/** ADC2 register map base pointer. */
|
|
||||||
#define ADC2_BASE ((struct adc_reg_map*)0x40012800)
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
/** ADC3 register map base pointer. */
|
|
||||||
#define ADC3_BASE ((struct adc_reg_map*)0x40013C00)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register bit definitions
|
* Register bit definitions
|
||||||
|
@ -167,17 +154,10 @@ extern const adc_dev *ADC3;
|
||||||
#define ADC_CR2_JEXTTRIG_BIT 15
|
#define ADC_CR2_JEXTTRIG_BIT 15
|
||||||
#define ADC_CR2_EXTTRIG_BIT 20
|
#define ADC_CR2_EXTTRIG_BIT 20
|
||||||
#define ADC_CR2_TSEREFE_BIT 23
|
#define ADC_CR2_TSEREFE_BIT 23
|
||||||
#ifdef STM32F2
|
|
||||||
#define ADC_CR2_JSWSTART_BIT 22
|
#define ADC_CR2_JSWSTART_BIT 22
|
||||||
#define ADC_CR2_SWSTART_BIT 30
|
#define ADC_CR2_SWSTART_BIT 30
|
||||||
#define ADC_CR2_EXTSEL (0x0F000000)
|
#define ADC_CR2_EXTSEL (0x0F000000)
|
||||||
#define ADC_CR2_JEXTSEL (0x000F0000)
|
#define ADC_CR2_JEXTSEL (0x000F0000)
|
||||||
#else
|
|
||||||
#define ADC_CR2_JSWSTART_BIT 21
|
|
||||||
#define ADC_CR2_SWSTART_BIT 22
|
|
||||||
#define ADC_CR2_EXTSEL (0x000E0000)
|
|
||||||
#define ADC_CR2_JEXTSEL (0x00007000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -388,7 +368,7 @@ static inline void adc_disable_all(void) {
|
||||||
adc_foreach(adc_disable);
|
adc_foreach(adc_disable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupADC_F2();
|
extern void setupADC_F4(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -126,11 +126,11 @@ void dac_enable_channel(const dac_dev *dev, uint8 channel) {
|
||||||
*/
|
*/
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case 1:
|
case 1:
|
||||||
gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG);
|
gpio_set_mode((uint8_t)PA4, GPIO_INPUT_ANALOG);
|
||||||
dev->regs->CR |= DAC_CR_EN1;
|
dev->regs->CR |= DAC_CR_EN1;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG);
|
gpio_set_mode((uint8_t)PA5, GPIO_INPUT_ANALOG);
|
||||||
dev->regs->CR |= DAC_CR_EN2;
|
dev->regs->CR |= DAC_CR_EN2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,4 @@
|
||||||
* @brief Direct Memory Access peripheral support
|
* @brief Direct Memory Access peripheral support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STM32F2
|
#include "dmaF4.h"
|
||||||
#include "dmaF2.h"
|
|
||||||
#include <libmaple/dma_common.h>
|
|
||||||
#else
|
|
||||||
#include "dmaF1.h"
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,383 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef STM32F1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file dma.c
|
|
||||||
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
|
||||||
* Original implementation by Michael Hope
|
|
||||||
* @brief Direct Memory Access peripheral support
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dma.h"
|
|
||||||
#include "bitband.h"
|
|
||||||
#include "util.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 }}
|
|
||||||
};
|
|
||||||
/** DMA1 device */
|
|
||||||
dma_dev *DMA1 = &dma1;
|
|
||||||
|
|
||||||
#ifdef STM32_HIGH_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 }} /* !@#$ */
|
|
||||||
};
|
|
||||||
/** DMA2 device */
|
|
||||||
dma_dev *DMA2 = &dma2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize a DMA device.
|
|
||||||
* @param dev Device to initialize.
|
|
||||||
*/
|
|
||||||
void dma_init(dma_dev *dev) {
|
|
||||||
rcc_clk_enable(dev->clk_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 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
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the number of data to be transferred on a DMA channel.
|
|
||||||
*
|
|
||||||
* You may not call this function while the channel is enabled.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel through which the transfer occurs.
|
|
||||||
* @param num_transfers
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the priority of a DMA transfer.
|
|
||||||
*
|
|
||||||
* You may not call this function while the channel is enabled.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel DMA channel
|
|
||||||
* @param priority priority to set.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
channel_regs->CCR = ccr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Attach an interrupt to a DMA transfer.
|
|
||||||
*
|
|
||||||
* Interrupts are enabled using appropriate mode flags in
|
|
||||||
* dma_setup_transfer().
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel to attach handler to
|
|
||||||
* @param handler Interrupt handler to call when channel interrupt fires.
|
|
||||||
* @see dma_setup_transfer()
|
|
||||||
* @see dma_get_irq_cause()
|
|
||||||
* @see dma_detach_interrupt()
|
|
||||||
*/
|
|
||||||
void dma_attach_interrupt(dma_dev *dev,
|
|
||||||
dma_channel channel,
|
|
||||||
void (*handler)(void)) {
|
|
||||||
dev->handlers[channel - 1].handler = handler;
|
|
||||||
nvic_irq_enable(dev->handlers[channel - 1].irq_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Detach a DMA transfer interrupt handler.
|
|
||||||
*
|
|
||||||
* After calling this function, the given channel's interrupts will be
|
|
||||||
* disabled.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel whose handler to detach
|
|
||||||
* @sideeffect Clears interrupt enable bits in the channel's CCR register.
|
|
||||||
* @see dma_attach_interrupt()
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
dev->handlers[channel - 1].handler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Discover the reason why a DMA interrupt was called.
|
|
||||||
*
|
|
||||||
* You may only call this function within an attached interrupt
|
|
||||||
* handler for the given channel.
|
|
||||||
*
|
|
||||||
* This function resets the internal DMA register state which encodes
|
|
||||||
* the cause of the interrupt; consequently, it can only be called
|
|
||||||
* once per interrupt handler invocation.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel whose interrupt is being handled.
|
|
||||||
* @return Reason why the interrupt fired.
|
|
||||||
* @sideeffect Clears channel status flags in dev->regs->ISR.
|
|
||||||
* @see dma_attach_interrupt()
|
|
||||||
* @see dma_irq_cause
|
|
||||||
*/
|
|
||||||
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
|
|
||||||
uint8 status_bits = dma_get_isr_bits(dev, channel);
|
|
||||||
|
|
||||||
/* If the channel global interrupt flag is cleared, then
|
|
||||||
* something's very wrong. */
|
|
||||||
ASSERT(status_bits & BIT(0));
|
|
||||||
|
|
||||||
dma_clear_isr_bits(dev, channel);
|
|
||||||
|
|
||||||
/* 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 & BIT(3)) {
|
|
||||||
return DMA_TRANSFER_ERROR;
|
|
||||||
} else if (status_bits & BIT(1)) {
|
|
||||||
return DMA_TRANSFER_COMPLETE;
|
|
||||||
} else if (status_bits & BIT(2)) {
|
|
||||||
return DMA_TRANSFER_HALF_COMPLETE;
|
|
||||||
} else if (status_bits & BIT(0)) {
|
|
||||||
/* Shouldn't happen (unless someone messed up an IFCR write). */
|
|
||||||
throb();
|
|
||||||
}
|
|
||||||
#if DEBUG_LEVEL < DEBUG_ALL
|
|
||||||
else {
|
|
||||||
/* We shouldn't have been called, but the debug level is too
|
|
||||||
* low for the above ASSERT() to have had any effect. In
|
|
||||||
* order to fail fast, mimic the DMA controller's behavior
|
|
||||||
* when an error occurs. */
|
|
||||||
dma_disable(dev, channel);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return DMA_TRANSFER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable a DMA channel.
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel to enable
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disable a DMA channel.
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel to disable
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the base memory address where data will be read from or
|
|
||||||
* written to.
|
|
||||||
*
|
|
||||||
* You must not call this function while the channel is enabled.
|
|
||||||
*
|
|
||||||
* If the DMA memory size is 16 bits, the address is automatically
|
|
||||||
* aligned to a half-word. If the DMA memory size is 32 bits, the
|
|
||||||
* address is aligned to a word.
|
|
||||||
*
|
|
||||||
* @param dev DMA Device
|
|
||||||
* @param channel Channel whose base memory address to set.
|
|
||||||
* @param addr Memory base address to use.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the base peripheral address where data will be read from
|
|
||||||
* or written to.
|
|
||||||
*
|
|
||||||
* You must not call this function while the channel is enabled.
|
|
||||||
*
|
|
||||||
* If the DMA peripheral size is 16 bits, the address is automatically
|
|
||||||
* aligned to a half-word. If the DMA peripheral size is 32 bits, the
|
|
||||||
* address is aligned to a word.
|
|
||||||
*
|
|
||||||
* @param dev DMA Device
|
|
||||||
* @param channel Channel whose peripheral data register base address to set.
|
|
||||||
* @param addr Peripheral memory base address to use.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IRQ handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void dispatch_handler(dma_dev *dev, dma_channel channel) {
|
|
||||||
void (*handler)(void) = dev->handlers[channel - 1].handler;
|
|
||||||
if (handler) {
|
|
||||||
handler();
|
|
||||||
dma_clear_isr_bits(dev, channel); /* in case handler doesn't */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel1(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel2(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel3(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel4(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel5(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH5);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel6(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma1_channel7(void) {
|
|
||||||
dispatch_handler(DMA1, DMA_CH7);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
void __irq_dma2_channel1(void) {
|
|
||||||
dispatch_handler(DMA2, DMA_CH1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma2_channel2(void) {
|
|
||||||
dispatch_handler(DMA2, DMA_CH2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma2_channel3(void) {
|
|
||||||
dispatch_handler(DMA2, DMA_CH3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __irq_dma2_channel4_5(void) {
|
|
||||||
dispatch_handler(DMA2, DMA_CH4);
|
|
||||||
dispatch_handler(DMA2, DMA_CH5);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,453 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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 dma.h
|
|
||||||
*
|
|
||||||
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
|
||||||
* Original implementation by Michael Hope
|
|
||||||
*
|
|
||||||
* @brief Direct Memory Access peripheral support
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See /notes/dma.txt for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DMA_H_
|
|
||||||
#define _DMA_H_
|
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
#include "rcc.h"
|
|
||||||
#include "nvic.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register maps
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief DMA register map type.
|
|
||||||
*
|
|
||||||
* Note that DMA controller 2 (register map base pointer DMA2_BASE)
|
|
||||||
* only supports channels 1--5.
|
|
||||||
*/
|
|
||||||
typedef struct dma_reg_map {
|
|
||||||
__io uint32 ISR; /**< Interrupt status register */
|
|
||||||
__io uint32 IFCR; /**< Interrupt flag clear register */
|
|
||||||
__io uint32 CCR1; /**< Channel 1 configuration register */
|
|
||||||
__io uint32 CNDTR1; /**< Channel 1 number of data register */
|
|
||||||
__io uint32 CPAR1; /**< Channel 1 peripheral address register */
|
|
||||||
__io uint32 CMAR1; /**< Channel 1 memory address register */
|
|
||||||
const uint32 RESERVED1; /**< Reserved. */
|
|
||||||
__io uint32 CCR2; /**< Channel 2 configuration register */
|
|
||||||
__io uint32 CNDTR2; /**< Channel 2 number of data register */
|
|
||||||
__io uint32 CPAR2; /**< Channel 2 peripheral address register */
|
|
||||||
__io uint32 CMAR2; /**< Channel 2 memory address register */
|
|
||||||
const uint32 RESERVED2; /**< Reserved. */
|
|
||||||
__io uint32 CCR3; /**< Channel 3 configuration register */
|
|
||||||
__io uint32 CNDTR3; /**< Channel 3 number of data register */
|
|
||||||
__io uint32 CPAR3; /**< Channel 3 peripheral address register */
|
|
||||||
__io uint32 CMAR3; /**< Channel 3 memory address register */
|
|
||||||
const uint32 RESERVED3; /**< Reserved. */
|
|
||||||
__io uint32 CCR4; /**< Channel 4 configuration register */
|
|
||||||
__io uint32 CNDTR4; /**< Channel 4 number of data register */
|
|
||||||
__io uint32 CPAR4; /**< Channel 4 peripheral address register */
|
|
||||||
__io uint32 CMAR4; /**< Channel 4 memory address register */
|
|
||||||
const uint32 RESERVED4; /**< Reserved. */
|
|
||||||
__io uint32 CCR5; /**< Channel 5 configuration register */
|
|
||||||
__io uint32 CNDTR5; /**< Channel 5 number of data register */
|
|
||||||
__io uint32 CPAR5; /**< Channel 5 peripheral address register */
|
|
||||||
__io uint32 CMAR5; /**< Channel 5 memory address register */
|
|
||||||
const uint32 RESERVED5; /**< Reserved. */
|
|
||||||
__io uint32 CCR6; /**< Channel 6 configuration register */
|
|
||||||
__io uint32 CNDTR6; /**< Channel 6 number of data register */
|
|
||||||
__io uint32 CPAR6; /**< Channel 6 peripheral address register */
|
|
||||||
__io uint32 CMAR6; /**< Channel 6 memory address register */
|
|
||||||
const uint32 RESERVED6; /**< Reserved. */
|
|
||||||
__io uint32 CCR7; /**< Channel 7 configuration register */
|
|
||||||
__io uint32 CNDTR7; /**< Channel 7 number of data register */
|
|
||||||
__io uint32 CPAR7; /**< Channel 7 peripheral address register */
|
|
||||||
__io uint32 CMAR7; /**< Channel 7 memory address register */
|
|
||||||
const uint32 RESERVED7; /**< Reserved. */
|
|
||||||
} dma_reg_map;
|
|
||||||
|
|
||||||
/** DMA controller 1 register map base pointer */
|
|
||||||
#define DMA1_BASE ((struct dma_reg_map*)0x40020000)
|
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
/** DMA controller 2 register map base pointer */
|
|
||||||
#define DMA2_BASE ((struct dma_reg_map*)0x40020400)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register bit definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Interrupt status register */
|
|
||||||
|
|
||||||
#define DMA_ISR_TEIF7_BIT 27
|
|
||||||
#define DMA_ISR_HTIF7_BIT 26
|
|
||||||
#define DMA_ISR_TCIF7_BIT 25
|
|
||||||
#define DMA_ISR_GIF7_BIT 24
|
|
||||||
#define DMA_ISR_TEIF6_BIT 23
|
|
||||||
#define DMA_ISR_HTIF6_BIT 22
|
|
||||||
#define DMA_ISR_TCIF6_BIT 21
|
|
||||||
#define DMA_ISR_GIF6_BIT 20
|
|
||||||
#define DMA_ISR_TEIF5_BIT 19
|
|
||||||
#define DMA_ISR_HTIF5_BIT 18
|
|
||||||
#define DMA_ISR_TCIF5_BIT 17
|
|
||||||
#define DMA_ISR_GIF5_BIT 16
|
|
||||||
#define DMA_ISR_TEIF4_BIT 15
|
|
||||||
#define DMA_ISR_HTIF4_BIT 14
|
|
||||||
#define DMA_ISR_TCIF4_BIT 13
|
|
||||||
#define DMA_ISR_GIF4_BIT 12
|
|
||||||
#define DMA_ISR_TEIF3_BIT 11
|
|
||||||
#define DMA_ISR_HTIF3_BIT 10
|
|
||||||
#define DMA_ISR_TCIF3_BIT 9
|
|
||||||
#define DMA_ISR_GIF3_BIT 8
|
|
||||||
#define DMA_ISR_TEIF2_BIT 7
|
|
||||||
#define DMA_ISR_HTIF2_BIT 6
|
|
||||||
#define DMA_ISR_TCIF2_BIT 5
|
|
||||||
#define DMA_ISR_GIF2_BIT 4
|
|
||||||
#define DMA_ISR_TEIF1_BIT 3
|
|
||||||
#define DMA_ISR_HTIF1_BIT 2
|
|
||||||
#define DMA_ISR_TCIF1_BIT 1
|
|
||||||
#define DMA_ISR_GIF1_BIT 0
|
|
||||||
|
|
||||||
#define DMA_ISR_TEIF7 BIT(DMA_ISR_TEIF7_BIT)
|
|
||||||
#define DMA_ISR_HTIF7 BIT(DMA_ISR_HTIF7_BIT)
|
|
||||||
#define DMA_ISR_TCIF7 BIT(DMA_ISR_TCIF7_BIT)
|
|
||||||
#define DMA_ISR_GIF7 BIT(DMA_ISR_GIF7_BIT)
|
|
||||||
#define DMA_ISR_TEIF6 BIT(DMA_ISR_TEIF6_BIT)
|
|
||||||
#define DMA_ISR_HTIF6 BIT(DMA_ISR_HTIF6_BIT)
|
|
||||||
#define DMA_ISR_TCIF6 BIT(DMA_ISR_TCIF6_BIT)
|
|
||||||
#define DMA_ISR_GIF6 BIT(DMA_ISR_GIF6_BIT)
|
|
||||||
#define DMA_ISR_TEIF5 BIT(DMA_ISR_TEIF5_BIT)
|
|
||||||
#define DMA_ISR_HTIF5 BIT(DMA_ISR_HTIF5_BIT)
|
|
||||||
#define DMA_ISR_TCIF5 BIT(DMA_ISR_TCIF5_BIT)
|
|
||||||
#define DMA_ISR_GIF5 BIT(DMA_ISR_GIF5_BIT)
|
|
||||||
#define DMA_ISR_TEIF4 BIT(DMA_ISR_TEIF4_BIT)
|
|
||||||
#define DMA_ISR_HTIF4 BIT(DMA_ISR_HTIF4_BIT)
|
|
||||||
#define DMA_ISR_TCIF4 BIT(DMA_ISR_TCIF4_BIT)
|
|
||||||
#define DMA_ISR_GIF4 BIT(DMA_ISR_GIF4_BIT)
|
|
||||||
#define DMA_ISR_TEIF3 BIT(DMA_ISR_TEIF3_BIT)
|
|
||||||
#define DMA_ISR_HTIF3 BIT(DMA_ISR_HTIF3_BIT)
|
|
||||||
#define DMA_ISR_TCIF3 BIT(DMA_ISR_TCIF3_BIT)
|
|
||||||
#define DMA_ISR_GIF3 BIT(DMA_ISR_GIF3_BIT)
|
|
||||||
#define DMA_ISR_TEIF2 BIT(DMA_ISR_TEIF2_BIT)
|
|
||||||
#define DMA_ISR_HTIF2 BIT(DMA_ISR_HTIF2_BIT)
|
|
||||||
#define DMA_ISR_TCIF2 BIT(DMA_ISR_TCIF2_BIT)
|
|
||||||
#define DMA_ISR_GIF2 BIT(DMA_ISR_GIF2_BIT)
|
|
||||||
#define DMA_ISR_TEIF1 BIT(DMA_ISR_TEIF1_BIT)
|
|
||||||
#define DMA_ISR_HTIF1 BIT(DMA_ISR_HTIF1_BIT)
|
|
||||||
#define DMA_ISR_TCIF1 BIT(DMA_ISR_TCIF1_BIT)
|
|
||||||
#define DMA_ISR_GIF1 BIT(DMA_ISR_GIF1_BIT)
|
|
||||||
|
|
||||||
/* Interrupt flag clear register */
|
|
||||||
|
|
||||||
#define DMA_IFCR_CTEIF7_BIT 27
|
|
||||||
#define DMA_IFCR_CHTIF7_BIT 26
|
|
||||||
#define DMA_IFCR_CTCIF7_BIT 25
|
|
||||||
#define DMA_IFCR_CGIF7_BIT 24
|
|
||||||
#define DMA_IFCR_CTEIF6_BIT 23
|
|
||||||
#define DMA_IFCR_CHTIF6_BIT 22
|
|
||||||
#define DMA_IFCR_CTCIF6_BIT 21
|
|
||||||
#define DMA_IFCR_CGIF6_BIT 20
|
|
||||||
#define DMA_IFCR_CTEIF5_BIT 19
|
|
||||||
#define DMA_IFCR_CHTIF5_BIT 18
|
|
||||||
#define DMA_IFCR_CTCIF5_BIT 17
|
|
||||||
#define DMA_IFCR_CGIF5_BIT 16
|
|
||||||
#define DMA_IFCR_CTEIF4_BIT 15
|
|
||||||
#define DMA_IFCR_CHTIF4_BIT 14
|
|
||||||
#define DMA_IFCR_CTCIF4_BIT 13
|
|
||||||
#define DMA_IFCR_CGIF4_BIT 12
|
|
||||||
#define DMA_IFCR_CTEIF3_BIT 11
|
|
||||||
#define DMA_IFCR_CHTIF3_BIT 10
|
|
||||||
#define DMA_IFCR_CTCIF3_BIT 9
|
|
||||||
#define DMA_IFCR_CGIF3_BIT 8
|
|
||||||
#define DMA_IFCR_CTEIF2_BIT 7
|
|
||||||
#define DMA_IFCR_CHTIF2_BIT 6
|
|
||||||
#define DMA_IFCR_CTCIF2_BIT 5
|
|
||||||
#define DMA_IFCR_CGIF2_BIT 4
|
|
||||||
#define DMA_IFCR_CTEIF1_BIT 3
|
|
||||||
#define DMA_IFCR_CHTIF1_BIT 2
|
|
||||||
#define DMA_IFCR_CTCIF1_BIT 1
|
|
||||||
#define DMA_IFCR_CGIF1_BIT 0
|
|
||||||
|
|
||||||
#define DMA_IFCR_CTEIF7 BIT(DMA_IFCR_CTEIF7_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF7 BIT(DMA_IFCR_CHTIF7_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF7 BIT(DMA_IFCR_CTCIF7_BIT)
|
|
||||||
#define DMA_IFCR_CGIF7 BIT(DMA_IFCR_CGIF7_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF6 BIT(DMA_IFCR_CTEIF6_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF6 BIT(DMA_IFCR_CHTIF6_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF6 BIT(DMA_IFCR_CTCIF6_BIT)
|
|
||||||
#define DMA_IFCR_CGIF6 BIT(DMA_IFCR_CGIF6_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF5 BIT(DMA_IFCR_CTEIF5_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF5 BIT(DMA_IFCR_CHTIF5_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF5 BIT(DMA_IFCR_CTCIF5_BIT)
|
|
||||||
#define DMA_IFCR_CGIF5 BIT(DMA_IFCR_CGIF5_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF4 BIT(DMA_IFCR_CTEIF4_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF4 BIT(DMA_IFCR_CHTIF4_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF4 BIT(DMA_IFCR_CTCIF4_BIT)
|
|
||||||
#define DMA_IFCR_CGIF4 BIT(DMA_IFCR_CGIF4_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF3 BIT(DMA_IFCR_CTEIF3_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF3 BIT(DMA_IFCR_CHTIF3_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF3 BIT(DMA_IFCR_CTCIF3_BIT)
|
|
||||||
#define DMA_IFCR_CGIF3 BIT(DMA_IFCR_CGIF3_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF2 BIT(DMA_IFCR_CTEIF2_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF2 BIT(DMA_IFCR_CHTIF2_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF2 BIT(DMA_IFCR_CTCIF2_BIT)
|
|
||||||
#define DMA_IFCR_CGIF2 BIT(DMA_IFCR_CGIF2_BIT)
|
|
||||||
#define DMA_IFCR_CTEIF1 BIT(DMA_IFCR_CTEIF1_BIT)
|
|
||||||
#define DMA_IFCR_CHTIF1 BIT(DMA_IFCR_CHTIF1_BIT)
|
|
||||||
#define DMA_IFCR_CTCIF1 BIT(DMA_IFCR_CTCIF1_BIT)
|
|
||||||
#define DMA_IFCR_CGIF1 BIT(DMA_IFCR_CGIF1_BIT)
|
|
||||||
|
|
||||||
/* Channel configuration register */
|
|
||||||
|
|
||||||
#define DMA_CCR_MEM2MEM_BIT 14
|
|
||||||
#define DMA_CCR_MINC_BIT 7
|
|
||||||
#define DMA_CCR_PINC_BIT 6
|
|
||||||
#define DMA_CCR_CIRC_BIT 5
|
|
||||||
#define DMA_CCR_DIR_BIT 4
|
|
||||||
#define DMA_CCR_TEIE_BIT 3
|
|
||||||
#define DMA_CCR_HTIE_BIT 2
|
|
||||||
#define DMA_CCR_TCIE_BIT 1
|
|
||||||
#define DMA_CCR_EN_BIT 0
|
|
||||||
|
|
||||||
#define DMA_CCR_MEM2MEM BIT(DMA_CCR_MEM2MEM_BIT)
|
|
||||||
#define DMA_CCR_PL (0x3 << 12)
|
|
||||||
#define DMA_CCR_PL_LOW (0x0 << 12)
|
|
||||||
#define DMA_CCR_PL_MEDIUM (0x1 << 12)
|
|
||||||
#define DMA_CCR_PL_HIGH (0x2 << 12)
|
|
||||||
#define DMA_CCR_PL_VERY_HIGH (0x3 << 12)
|
|
||||||
#define DMA_CCR_MSIZE (0x3 << 10)
|
|
||||||
#define DMA_CCR_MSIZE_8BITS (0x0 << 10)
|
|
||||||
#define DMA_CCR_MSIZE_16BITS (0x1 << 10)
|
|
||||||
#define DMA_CCR_MSIZE_32BITS (0x2 << 10)
|
|
||||||
#define DMA_CCR_PSIZE (0x3 << 8)
|
|
||||||
#define DMA_CCR_PSIZE_8BITS (0x0 << 8)
|
|
||||||
#define DMA_CCR_PSIZE_16BITS (0x1 << 8)
|
|
||||||
#define DMA_CCR_PSIZE_32BITS (0x2 << 8)
|
|
||||||
#define DMA_CCR_MINC BIT(DMA_CCR_MINC_BIT)
|
|
||||||
#define DMA_CCR_PINC BIT(DMA_CCR_PINC_BIT)
|
|
||||||
#define DMA_CCR_CIRC BIT(DMA_CCR_CIRC_BIT)
|
|
||||||
#define DMA_CCR_DIR BIT(DMA_CCR_DIR_BIT)
|
|
||||||
#define DMA_CCR_TEIE BIT(DMA_CCR_TEIE_BIT)
|
|
||||||
#define DMA_CCR_HTIE BIT(DMA_CCR_HTIE_BIT)
|
|
||||||
#define DMA_CCR_TCIE BIT(DMA_CCR_TCIE_BIT)
|
|
||||||
#define DMA_CCR_EN BIT(DMA_CCR_EN_BIT)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Devices
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Encapsulates state related to a DMA channel interrupt. */
|
|
||||||
typedef struct dma_handler_config {
|
|
||||||
void (*handler)(void); /**< User-specified channel interrupt
|
|
||||||
handler */
|
|
||||||
nvic_irq_num irq_line; /**< Channel's NVIC interrupt number */
|
|
||||||
} dma_handler_config;
|
|
||||||
|
|
||||||
/** DMA device type */
|
|
||||||
typedef struct dma_dev {
|
|
||||||
dma_reg_map *regs; /**< Register map */
|
|
||||||
rcc_clk_id clk_id; /**< Clock ID */
|
|
||||||
dma_handler_config handlers[]; /**<
|
|
||||||
* @brief IRQ handlers and NVIC numbers.
|
|
||||||
*
|
|
||||||
* @see dma_attach_interrupt()
|
|
||||||
* @see dma_detach_interrupt()
|
|
||||||
*/
|
|
||||||
} dma_dev;
|
|
||||||
|
|
||||||
extern dma_dev *DMA1;
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
extern dma_dev *DMA2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
void dma_init(dma_dev *dev);
|
|
||||||
|
|
||||||
/** Flags for DMA transfer configuration. */
|
|
||||||
typedef enum dma_mode_flags {
|
|
||||||
DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */
|
|
||||||
DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */
|
|
||||||
DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */
|
|
||||||
DMA_CIRC_MODE = 1 << 5, /**< Circular mode */
|
|
||||||
DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */
|
|
||||||
DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */
|
|
||||||
DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */
|
|
||||||
DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
|
|
||||||
} dma_mode_flags;
|
|
||||||
|
|
||||||
/** Source and destination transfer sizes. */
|
|
||||||
typedef enum dma_xfer_size {
|
|
||||||
DMA_SIZE_8BITS = 0, /**< 8-bit transfers */
|
|
||||||
DMA_SIZE_16BITS = 1, /**< 16-bit transfers */
|
|
||||||
DMA_SIZE_32BITS = 2 /**< 32-bit transfers */
|
|
||||||
} dma_xfer_size;
|
|
||||||
|
|
||||||
/** DMA channel */
|
|
||||||
typedef enum dma_channel {
|
|
||||||
DMA_CH1 = 1, /**< Channel 1 */
|
|
||||||
DMA_CH2 = 2, /**< Channel 2 */
|
|
||||||
DMA_CH3 = 3, /**< Channel 3 */
|
|
||||||
DMA_CH4 = 4, /**< Channel 4 */
|
|
||||||
DMA_CH5 = 5, /**< Channel 5 */
|
|
||||||
DMA_CH6 = 6, /**< Channel 6 */
|
|
||||||
DMA_CH7 = 7, /**< Channel 7 */
|
|
||||||
} dma_channel;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
void dma_set_num_transfers(dma_dev *dev,
|
|
||||||
dma_channel channel,
|
|
||||||
uint16 num_transfers);
|
|
||||||
|
|
||||||
/** DMA transfer priority. */
|
|
||||||
typedef enum dma_priority {
|
|
||||||
DMA_PRIORITY_LOW = DMA_CCR_PL_LOW, /**< Low priority */
|
|
||||||
DMA_PRIORITY_MEDIUM = DMA_CCR_PL_MEDIUM, /**< Medium priority */
|
|
||||||
DMA_PRIORITY_HIGH = DMA_CCR_PL_HIGH, /**< High priority */
|
|
||||||
DMA_PRIORITY_VERY_HIGH = DMA_CCR_PL_VERY_HIGH /**< Very high priority */
|
|
||||||
} dma_priority;
|
|
||||||
|
|
||||||
void dma_set_priority(dma_dev *dev,
|
|
||||||
dma_channel channel,
|
|
||||||
dma_priority priority);
|
|
||||||
|
|
||||||
void dma_attach_interrupt(dma_dev *dev,
|
|
||||||
dma_channel channel,
|
|
||||||
void (*handler)(void));
|
|
||||||
void dma_detach_interrupt(dma_dev *dev, dma_channel channel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes the reason why a DMA interrupt was called.
|
|
||||||
* @see dma_get_irq_cause()
|
|
||||||
*/
|
|
||||||
typedef enum dma_irq_cause {
|
|
||||||
DMA_TRANSFER_COMPLETE, /**< Transfer is complete. */
|
|
||||||
DMA_TRANSFER_HALF_COMPLETE, /**< Transfer is half complete. */
|
|
||||||
DMA_TRANSFER_ERROR, /**< Error occurred during transfer. */
|
|
||||||
} dma_irq_cause;
|
|
||||||
|
|
||||||
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel);
|
|
||||||
|
|
||||||
void dma_enable(dma_dev *dev, dma_channel channel);
|
|
||||||
void dma_disable(dma_dev *dev, dma_channel channel);
|
|
||||||
|
|
||||||
void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *address);
|
|
||||||
void dma_set_per_addr(dma_dev *dev, dma_channel channel, __io void *address);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief DMA channel register map type.
|
|
||||||
*
|
|
||||||
* Provides access to an individual channel's registers.
|
|
||||||
*/
|
|
||||||
typedef struct dma_channel_reg_map {
|
|
||||||
__io uint32 CCR; /**< Channel configuration register */
|
|
||||||
__io uint32 CNDTR; /**< Channel number of data register */
|
|
||||||
__io uint32 CPAR; /**< Channel peripheral address register */
|
|
||||||
__io uint32 CMAR; /**< Channel memory address register */
|
|
||||||
} dma_channel_reg_map;
|
|
||||||
|
|
||||||
#define DMA_CHANNEL_NREGS 5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Obtain a pointer to an individual DMA channel's registers.
|
|
||||||
*
|
|
||||||
* For example, dma_channel_regs(DMA1, DMA_CH1)->CCR is DMA1_BASE->CCR1.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel DMA channel whose channel register map to obtain.
|
|
||||||
*/
|
|
||||||
static inline dma_channel_reg_map* dma_channel_regs(dma_dev *dev,
|
|
||||||
dma_channel channel) {
|
|
||||||
__io uint32 *ccr1 = &dev->regs->CCR1;
|
|
||||||
return (dma_channel_reg_map*)(ccr1 + DMA_CHANNEL_NREGS * (channel - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a DMA channel is enabled
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel whose enabled bit to check.
|
|
||||||
*/
|
|
||||||
static inline uint8 dma_is_channel_enabled(dma_dev *dev, dma_channel channel) {
|
|
||||||
return (uint8)(dma_channel_regs(dev, channel)->CCR & DMA_CCR_EN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the ISR status bits for a DMA channel.
|
|
||||||
*
|
|
||||||
* The bits are returned right-aligned, in the following order:
|
|
||||||
* transfer error flag, half-transfer flag, transfer complete flag,
|
|
||||||
* global interrupt flag.
|
|
||||||
*
|
|
||||||
* If you're attempting to figure out why a DMA interrupt fired; you
|
|
||||||
* may find dma_get_irq_cause() more convenient.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel whose ISR bits to return.
|
|
||||||
* @see dma_get_irq_cause().
|
|
||||||
*/
|
|
||||||
static inline uint8 dma_get_isr_bits(dma_dev *dev, dma_channel channel) {
|
|
||||||
uint8 shift = (channel - 1) * 4;
|
|
||||||
return (dev->regs->ISR >> shift) & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clear the ISR status bits for a given DMA channel.
|
|
||||||
*
|
|
||||||
* If you're attempting to clean up after yourself in a DMA interrupt,
|
|
||||||
* you may find dma_get_irq_cause() more convenient.
|
|
||||||
*
|
|
||||||
* @param dev DMA device
|
|
||||||
* @param channel Channel whose ISR bits to clear.
|
|
||||||
* @see dma_get_irq_cause()
|
|
||||||
*/
|
|
||||||
static inline void dma_clear_isr_bits(dma_dev *dev, dma_channel channel) {
|
|
||||||
dev->regs->IFCR = BIT(4 * (channel - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -24,10 +24,10 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifdef STM32F2
|
#ifdef STM32F4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file dmaF2.c
|
* @file dmaF4.c
|
||||||
* @brief Direct Memory Access peripheral support
|
* @brief Direct Memory Access peripheral support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -117,33 +117,16 @@ void dma_detach_interrupt(dma_dev *dev, dma_stream stream) {
|
||||||
dev->handlers[stream].handler = NULL;
|
dev->handlers[stream].handler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8 dma_isr_bits_shift[] = { 0, 6, 16, 22};
|
||||||
|
|
||||||
|
uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream) {
|
||||||
|
if ( stream&0xFC ) return ((dev->regs->HISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d;
|
||||||
|
else return ((dev->regs->LISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d;
|
||||||
|
}
|
||||||
|
|
||||||
void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) {
|
void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) {
|
||||||
switch (stream) {
|
if ( stream&0xFC ) dev->regs->HIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03];
|
||||||
case 0:
|
else dev->regs->LIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03];
|
||||||
dev->regs->LIFCR|=0x0000003d;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
dev->regs->LIFCR|=0x00000f40;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
dev->regs->LIFCR|=0x003d0000;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
dev->regs->LIFCR|=0x0f400000;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
dev->regs->HIFCR|=0x0000003d;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
dev->regs->HIFCR|=0x00000f40;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
dev->regs->HIFCR|=0x003d0000;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
dev->regs->HIFCR|=0x0f400000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
|
@ -25,7 +25,7 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file dma.h
|
* @file dmaF4.h
|
||||||
*
|
*
|
||||||
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
* @author Marti Bolivar <mbolivar@leaflabs.com>;
|
||||||
* Original implementation by Michael Hope
|
* Original implementation by Michael Hope
|
||||||
|
@ -84,7 +84,7 @@ typedef struct dma_reg_map {
|
||||||
* Register bit definitions
|
* Register bit definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Channel configuration register */
|
/* Stream configuration register */
|
||||||
|
|
||||||
#define DMA_CR_CH0 (0x0 << 25)
|
#define DMA_CR_CH0 (0x0 << 25)
|
||||||
#define DMA_CR_CH1 (0x1 << 25)
|
#define DMA_CR_CH1 (0x1 << 25)
|
||||||
|
@ -136,6 +136,25 @@ typedef struct dma_reg_map {
|
||||||
#define DMA_CR_DMEIE (0x1 << 1)
|
#define DMA_CR_DMEIE (0x1 << 1)
|
||||||
#define DMA_CR_EN (0x1)
|
#define DMA_CR_EN (0x1)
|
||||||
|
|
||||||
|
typedef enum dma_channel {
|
||||||
|
DMA_CH0 = DMA_CR_CH0, /**< Channel 0 */
|
||||||
|
DMA_CH1 = DMA_CR_CH1, /**< Channel 1 */
|
||||||
|
DMA_CH2 = DMA_CR_CH2, /**< Channel 2 */
|
||||||
|
DMA_CH3 = DMA_CR_CH3, /**< Channel 3 */
|
||||||
|
DMA_CH4 = DMA_CR_CH4, /**< Channel 4 */
|
||||||
|
DMA_CH5 = DMA_CR_CH5, /**< Channel 5 */
|
||||||
|
DMA_CH6 = DMA_CR_CH6, /**< Channel 6 */
|
||||||
|
DMA_CH7 = DMA_CR_CH7, /**< Channel 7 */
|
||||||
|
} dma_channel;
|
||||||
|
|
||||||
|
/* Device interrupt status register flags */
|
||||||
|
|
||||||
|
#define DMA_ISR_TCIF (1 << 5)
|
||||||
|
#define DMA_ISR_HTIF (1 << 4)
|
||||||
|
#define DMA_ISR_TEIF (1 << 3)
|
||||||
|
#define DMA_ISR_DMEIF (1 << 2)
|
||||||
|
#define DMA_ISR_FEIF (1 << 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Devices
|
* Devices
|
||||||
*/
|
*/
|
||||||
|
@ -166,25 +185,35 @@ extern dma_dev *DMA2;
|
||||||
* Convenience functions
|
* Convenience functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void dma_init(dma_dev *dev);
|
extern void dma_init(dma_dev *dev);
|
||||||
|
|
||||||
/** Flags for DMA transfer configuration. */
|
/** Flags for DMA transfer configuration. */
|
||||||
typedef enum dma_mode_flags {
|
typedef enum dma_mode_flags {
|
||||||
DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */
|
DMA_MEM_BUF_0 = DMA_CR_CT0, /**< Current memory target buffer 0 */
|
||||||
DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */
|
DMA_MEM_BUF_1 = DMA_CR_CT1, /**< Current memory target buffer 1 */
|
||||||
DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */
|
DMA_DBL_BUF_MODE = DMA_CR_DBM, /**< Current memory double buffer mode */
|
||||||
DMA_CIRC_MODE = 1 << 5, /**< Circular mode */
|
DMA_PINC_OFFSET = DMA_CR_PINCOS, /**< Peripheral increment offset size */
|
||||||
DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */
|
DMA_MINC_MODE = DMA_CR_MINC, /**< Memory increment mode */
|
||||||
DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */
|
DMA_PINC_MODE = DMA_CR_PINC, /**< Peripheral increment mode */
|
||||||
DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */
|
DMA_CIRC_MODE = DMA_CR_CIRC, /**< Memory Circular mode */
|
||||||
DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
|
DMA_FROM_PER = DMA_CR_DIR_P2M, /**< Read from memory to peripheral */
|
||||||
|
DMA_FROM_MEM = DMA_CR_DIR_M2P, /**< Read from memory to peripheral */
|
||||||
|
DMA_MEM_TO_MEM = DMA_CR_DIR_M2M, /**< Read from memory to memory */
|
||||||
|
DMA_PERIF_CTRL = DMA_CR_PFCTRL, /**< Peripheral flow controller */
|
||||||
|
DMA_PRIO_MEDIUM = DMA_CR_PL_MEDIUM, /**< Medium priority */
|
||||||
|
DMA_PRIO_HIGH = DMA_CR_PL_HIGH, /**< High priority */
|
||||||
|
DMA_PRIO_VERY_HIGH = DMA_CR_PL_VERY_HIGH, /**< Very high priority */
|
||||||
|
DMA_TRNS_CMPLT = DMA_CR_TCIE, /**< Interrupt on transfer completion */
|
||||||
|
DMA_TRNS_HALF = DMA_CR_HTIE, /**< Interrupt on half-transfer */
|
||||||
|
DMA_TRNS_ERR = DMA_CR_TEIE, /**< Interrupt on transfer error */
|
||||||
|
DMA_DIR_MODE_ERR = DMA_CR_DMEIE /**< Interrupt on direct mode error */
|
||||||
} dma_mode_flags;
|
} dma_mode_flags;
|
||||||
|
|
||||||
/** Source and destination transfer sizes. */
|
/** Source and destination transfer sizes. */
|
||||||
typedef enum dma_xfer_size {
|
typedef enum dma_xfer_size {
|
||||||
DMA_SIZE_8BITS = 0, /**< 8-bit transfers */
|
DMA_SIZE_8BITS = ( DMA_CR_MSIZE_8BITS|DMA_CR_PSIZE_8BITS ), /**< 8-bit transfers */
|
||||||
DMA_SIZE_16BITS = 1, /**< 16-bit transfers */
|
DMA_SIZE_16BITS = (DMA_CR_MSIZE_16BITS|DMA_CR_PSIZE_16BITS), /**< 16-bit transfers */
|
||||||
DMA_SIZE_32BITS = 2 /**< 32-bit transfers */
|
DMA_SIZE_32BITS = (DMA_CR_MSIZE_32BITS|DMA_CR_PSIZE_32BITS) /**< 32-bit transfers */
|
||||||
} dma_xfer_size;
|
} dma_xfer_size;
|
||||||
|
|
||||||
/** DMA channel */
|
/** DMA channel */
|
||||||
|
@ -201,17 +230,17 @@ typedef enum dma_stream {
|
||||||
|
|
||||||
static inline void dma_setup_transfer(dma_dev *dev,
|
static inline void dma_setup_transfer(dma_dev *dev,
|
||||||
dma_stream stream,
|
dma_stream stream,
|
||||||
|
dma_channel channel,
|
||||||
|
dma_xfer_size trx_size,
|
||||||
__io void *peripheral_address,
|
__io void *peripheral_address,
|
||||||
__io void *memory_address0,
|
__io void *memory_address0,
|
||||||
__io void *memory_address1,
|
__io void *memory_address1,
|
||||||
uint32 flags,
|
uint32 flags) {
|
||||||
uint32 fifo_flags) {
|
|
||||||
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable
|
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable
|
||||||
dev->regs->STREAM[stream].PAR = (uint32)peripheral_address;
|
dev->regs->STREAM[stream].PAR = (uint32)peripheral_address;
|
||||||
dev->regs->STREAM[stream].M0AR = (uint32)memory_address0;
|
dev->regs->STREAM[stream].M0AR = (uint32)memory_address0;
|
||||||
dev->regs->STREAM[stream].M1AR = (uint32)memory_address1;
|
dev->regs->STREAM[stream].M1AR = (uint32)memory_address1;
|
||||||
dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits
|
dev->regs->STREAM[stream].CR = ((flags|channel|trx_size) & 0x0feffffe); // mask out reserved and enable
|
||||||
dev->regs->STREAM[stream].CR = flags & 0x0feffffe; // mask out reserved and enable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dma_set_num_transfers(dma_dev *dev,
|
static inline void dma_set_num_transfers(dma_dev *dev,
|
||||||
|
@ -220,6 +249,12 @@ static inline void dma_set_num_transfers(dma_dev *dev,
|
||||||
dev->regs->STREAM[stream].NDTR = num_transfers;
|
dev->regs->STREAM[stream].NDTR = num_transfers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dma_set_fifo_flags(dma_dev *dev,
|
||||||
|
dma_stream stream,
|
||||||
|
uint8 fifo_flags) {
|
||||||
|
dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits
|
||||||
|
}
|
||||||
|
|
||||||
void dma_attach_interrupt(dma_dev *dev,
|
void dma_attach_interrupt(dma_dev *dev,
|
||||||
dma_stream stream,
|
dma_stream stream,
|
||||||
void (*handler)(void));
|
void (*handler)(void));
|
||||||
|
@ -232,6 +267,7 @@ static inline void dma_enable(dma_dev *dev, dma_stream stream) {
|
||||||
|
|
||||||
static inline void dma_disable(dma_dev *dev, dma_stream stream) {
|
static inline void dma_disable(dma_dev *dev, dma_stream stream) {
|
||||||
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN;
|
dev->regs->STREAM[stream].CR &= ~DMA_CR_EN;
|
||||||
|
while (dev->regs->STREAM[stream].CR & DMA_CR_EN); // wait till EN bit is reset, see AN4031, chapter 4.1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -52,11 +52,7 @@ typedef struct exti_reg_map {
|
||||||
} exti_reg_map;
|
} exti_reg_map;
|
||||||
|
|
||||||
/** EXTI register map base pointer */
|
/** EXTI register map base pointer */
|
||||||
#ifdef STM32F2
|
|
||||||
#define EXTI_BASE ((struct exti_reg_map*)0x40013C00)
|
#define EXTI_BASE ((struct exti_reg_map*)0x40013C00)
|
||||||
#else
|
|
||||||
#define EXTI_BASE ((struct exti_reg_map*)0x40010400)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** External interrupt trigger mode */
|
/** External interrupt trigger mode */
|
||||||
typedef enum exti_trigger_mode {
|
typedef enum exti_trigger_mode {
|
||||||
|
|
|
@ -39,27 +39,28 @@
|
||||||
*/
|
*/
|
||||||
void fsmc_sram_init_gpios(void) {
|
void fsmc_sram_init_gpios(void) {
|
||||||
/* Data lines... */
|
/* Data lines... */
|
||||||
gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD0, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD1, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD8, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD9, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD10, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD14, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD15, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE7, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE8, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE9, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE10, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE11, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE12, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE13, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE14, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PE15, GPIO_AF_OUTPUT_PP);
|
||||||
|
|
||||||
/* Address lines... */
|
/* Address lines... */
|
||||||
gpio_set_mode(GPIOD, 11, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD11, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 12, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD12, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOD, 13, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(PD13, GPIO_AF_OUTPUT_PP);
|
||||||
|
#if 0 // not available on LQFP package
|
||||||
gpio_set_mode(GPIOF, 0, 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, 1, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP);
|
||||||
|
@ -76,18 +77,20 @@ void fsmc_sram_init_gpios(void) {
|
||||||
gpio_set_mode(GPIOG, 3, 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, 4, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP);
|
||||||
|
#endif // not available on LQFP package
|
||||||
/* And control lines... */
|
/* And control lines... */
|
||||||
gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // NOE
|
gpio_set_mode(PD4, GPIO_AF_OUTPUT_PP); // NOE
|
||||||
gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // NWE
|
gpio_set_mode(PD5, GPIO_AF_OUTPUT_PP); // NWE
|
||||||
|
|
||||||
gpio_set_mode(GPIOD, 7, GPIO_AF_OUTPUT_PP); // NE1
|
gpio_set_mode(PD7, GPIO_AF_OUTPUT_PP); // NE1
|
||||||
|
#if 0 // not available on LQFP package
|
||||||
gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2
|
gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2
|
||||||
gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3
|
gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3
|
||||||
gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4
|
gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4
|
||||||
|
#endif // not available on LQFP package
|
||||||
|
|
||||||
gpio_set_mode(GPIOE, 0, GPIO_AF_OUTPUT_PP); // NBL0
|
gpio_set_mode(PE0, GPIO_AF_OUTPUT_PP); // NBL0
|
||||||
gpio_set_mode(GPIOE, 1, GPIO_AF_OUTPUT_PP); // NBL1
|
gpio_set_mode(PE1, GPIO_AF_OUTPUT_PP); // NBL1
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* STM32_HIGH_DENSITY */
|
#endif /* STM32_HIGH_DENSITY */
|
||||||
|
|
|
@ -31,8 +31,102 @@
|
||||||
* (AFIO) prototypes, defines, and inlined access functions.
|
* (AFIO) prototypes, defines, and inlined access functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STM32F2
|
#ifndef _GPIO_H_
|
||||||
#include "gpioF2.h"
|
#define _GPIO_H_
|
||||||
#else
|
|
||||||
#include "gpioF1.h"
|
#include "libmaple.h"
|
||||||
|
#include "boards.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a GPIO port's corresponding afio_exti_port.
|
||||||
|
* @param dev GPIO device whose afio_exti_port to return.
|
||||||
|
*/
|
||||||
|
static inline afio_exti_port gpio_exti_port(const gpio_dev *dev) {
|
||||||
|
return dev->exti_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or reset a GPIO pin.
|
||||||
|
*
|
||||||
|
* Pin must have previously been configured to output mode.
|
||||||
|
*
|
||||||
|
* @param dev GPIO device whose pin to set.
|
||||||
|
* @param pin Pin on to set or reset
|
||||||
|
* @param val If true, set the pin. If false, reset the pin.
|
||||||
|
*/
|
||||||
|
static inline void gpio_write_pin(uint8_t pin, uint8 val) {
|
||||||
|
if (val) {
|
||||||
|
(PIN_MAP[pin].gpio_device)->regs->BSRRL = BIT(pin&0x0F);
|
||||||
|
} else {
|
||||||
|
(PIN_MAP[pin].gpio_device)->regs->BSRRH = BIT(pin&0x0F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_set_pin(uint8_t pin) {
|
||||||
|
(PIN_MAP[pin].gpio_device)->regs->BSRRL = BIT(pin&0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_clear_pin(uint8_t pin) {
|
||||||
|
(PIN_MAP[pin].gpio_device)->regs->BSRRH = BIT(pin&0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether or not a GPIO pin is set.
|
||||||
|
*
|
||||||
|
* Pin must have previously been configured to input mode.
|
||||||
|
*
|
||||||
|
* @param dev GPIO device whose pin to test.
|
||||||
|
* @param pin Pin on dev to test.
|
||||||
|
* @return True if the pin is set, false otherwise.
|
||||||
|
*/
|
||||||
|
static inline uint32 gpio_read_pin(uint8_t pin) {
|
||||||
|
return (PIN_MAP[pin].gpio_device)->regs->IDR & BIT(pin&0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle a pin configured as output push-pull.
|
||||||
|
* @param dev GPIO device.
|
||||||
|
* @param pin Pin on dev to toggle.
|
||||||
|
*/
|
||||||
|
static inline void gpio_toggle_pin(uint8_t pin) {
|
||||||
|
(PIN_MAP[pin].gpio_device)->regs->ODR = (PIN_MAP[pin].gpio_device)->regs->ODR ^ BIT(pin&0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO Convenience routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void gpio_init(const gpio_dev *dev);
|
||||||
|
extern void gpio_init_all(void);
|
||||||
|
extern void gpio_set_mode(uint8_t pin, gpio_pin_mode mode);
|
||||||
|
extern void gpio_set_af_mode(uint8_t pin, int mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AFIO convenience routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void afio_init(void);
|
||||||
|
extern void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
|
||||||
|
extern void afio_remap(afio_remap_peripheral p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable or disable the JTAG and SW debug ports.
|
||||||
|
* @param config Desired debug port configuration
|
||||||
|
* @see afio_debug_cfg
|
||||||
|
*/
|
||||||
|
static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
|
||||||
|
//__io uint32 *mapr = &AFIO_BASE->MAPR;
|
||||||
|
//*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef STM32F1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file gpio.c
|
|
||||||
* @brief GPIO initialization routine
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "rcc.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO devices
|
|
||||||
*/
|
|
||||||
|
|
||||||
gpio_dev gpioa = {
|
|
||||||
.regs = GPIOA_BASE,
|
|
||||||
.clk_id = RCC_GPIOA,
|
|
||||||
.exti_port = AFIO_EXTI_PA,
|
|
||||||
};
|
|
||||||
/** GPIO port A device. */
|
|
||||||
gpio_dev* const GPIOA = &gpioa;
|
|
||||||
|
|
||||||
gpio_dev gpiob = {
|
|
||||||
.regs = GPIOB_BASE,
|
|
||||||
.clk_id = RCC_GPIOB,
|
|
||||||
.exti_port = AFIO_EXTI_PB,
|
|
||||||
};
|
|
||||||
/** GPIO port B device. */
|
|
||||||
gpio_dev* const GPIOB = &gpiob;
|
|
||||||
|
|
||||||
gpio_dev gpioc = {
|
|
||||||
.regs = GPIOC_BASE,
|
|
||||||
.clk_id = RCC_GPIOC,
|
|
||||||
.exti_port = AFIO_EXTI_PC,
|
|
||||||
};
|
|
||||||
/** GPIO port C device. */
|
|
||||||
gpio_dev* const GPIOC = &gpioc;
|
|
||||||
|
|
||||||
gpio_dev gpiod = {
|
|
||||||
.regs = GPIOD_BASE,
|
|
||||||
.clk_id = RCC_GPIOD,
|
|
||||||
.exti_port = AFIO_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 = AFIO_EXTI_PE,
|
|
||||||
};
|
|
||||||
/** GPIO port E device. */
|
|
||||||
gpio_dev* const GPIOE = &gpioe;
|
|
||||||
|
|
||||||
gpio_dev gpiof = {
|
|
||||||
.regs = GPIOF_BASE,
|
|
||||||
.clk_id = RCC_GPIOF,
|
|
||||||
.exti_port = AFIO_EXTI_PF,
|
|
||||||
};
|
|
||||||
/** GPIO port F device. */
|
|
||||||
gpio_dev* const GPIOF = &gpiof;
|
|
||||||
|
|
||||||
gpio_dev gpiog = {
|
|
||||||
.regs = GPIOG_BASE,
|
|
||||||
.clk_id = RCC_GPIOG,
|
|
||||||
.exti_port = AFIO_EXTI_PG,
|
|
||||||
};
|
|
||||||
/** GPIO port G device. */
|
|
||||||
gpio_dev* const GPIOG = &gpiog;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO convenience 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 &= ~BIT(pin);
|
|
||||||
} else if (mode == GPIO_INPUT_PU) {
|
|
||||||
regs->ODR |= BIT(pin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 Select a source input for an external interrupt.
|
|
||||||
*
|
|
||||||
* @param exti External interrupt.
|
|
||||||
* @param gpio_port Port which contains pin to use as source input.
|
|
||||||
* @see afio_exti_num
|
|
||||||
* @see afio_exti_port
|
|
||||||
*/
|
|
||||||
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) {
|
|
||||||
__io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4;
|
|
||||||
uint32 shift = 4 * (exti % 4);
|
|
||||||
uint32 cr = *exti_cr;
|
|
||||||
|
|
||||||
cr &= ~(AFIO_EXTI_SEL_MASK << shift);
|
|
||||||
cr |= gpio_port << shift;
|
|
||||||
*exti_cr = cr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,530 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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 gpio.h
|
|
||||||
*
|
|
||||||
* @brief General purpose I/O (GPIO) and Alternate Function I/O
|
|
||||||
* (AFIO) prototypes, defines, and inlined access functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _GPIO_H_
|
|
||||||
#define _GPIO_H_
|
|
||||||
|
|
||||||
#include "libmaple.h"
|
|
||||||
#include "rcc.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO register maps and devices
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** GPIO register map type */
|
|
||||||
typedef struct gpio_reg_map {
|
|
||||||
__io uint32 CRL; /**< Port configuration register low */
|
|
||||||
__io uint32 CRH; /**< Port configuration register high */
|
|
||||||
__io uint32 IDR; /**< Port input data register */
|
|
||||||
__io uint32 ODR; /**< Port output data register */
|
|
||||||
__io uint32 BSRR; /**< Port bit set/reset register */
|
|
||||||
__io uint32 BRR; /**< Port bit reset register */
|
|
||||||
__io uint32 LCKR; /**< Port configuration lock register */
|
|
||||||
} gpio_reg_map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief External interrupt line port selector.
|
|
||||||
*
|
|
||||||
* Used to determine which GPIO port to map an external interrupt line
|
|
||||||
* onto. */
|
|
||||||
/* (See AFIO sections, below) */
|
|
||||||
typedef enum afio_exti_port {
|
|
||||||
AFIO_EXTI_PA, /**< Use port A (PAx) pin. */
|
|
||||||
AFIO_EXTI_PB, /**< Use port B (PBx) pin. */
|
|
||||||
AFIO_EXTI_PC, /**< Use port C (PCx) pin. */
|
|
||||||
AFIO_EXTI_PD, /**< Use port D (PDx) pin. */
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
AFIO_EXTI_PE, /**< Use port E (PEx) pin. */
|
|
||||||
AFIO_EXTI_PF, /**< Use port F (PFx) pin. */
|
|
||||||
AFIO_EXTI_PG, /**< Use port G (PGx) pin. */
|
|
||||||
#endif
|
|
||||||
} afio_exti_port;
|
|
||||||
|
|
||||||
/** GPIO device type */
|
|
||||||
typedef struct gpio_dev {
|
|
||||||
gpio_reg_map *regs; /**< Register map */
|
|
||||||
rcc_clk_id clk_id; /**< RCC clock information */
|
|
||||||
afio_exti_port exti_port; /**< AFIO external interrupt port value */
|
|
||||||
} gpio_dev;
|
|
||||||
|
|
||||||
extern gpio_dev gpioa;
|
|
||||||
extern gpio_dev* const GPIOA;
|
|
||||||
extern gpio_dev gpiob;
|
|
||||||
extern gpio_dev* const GPIOB;
|
|
||||||
extern gpio_dev gpioc;
|
|
||||||
extern gpio_dev* const GPIOC;
|
|
||||||
extern gpio_dev gpiod;
|
|
||||||
extern gpio_dev* const GPIOD;
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
extern gpio_dev gpioe;
|
|
||||||
extern gpio_dev* const GPIOE;
|
|
||||||
extern gpio_dev gpiof;
|
|
||||||
extern gpio_dev* const GPIOF;
|
|
||||||
extern gpio_dev gpiog;
|
|
||||||
extern gpio_dev* const GPIOG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** GPIO port A register map base pointer */
|
|
||||||
#define GPIOA_BASE ((struct gpio_reg_map*)0x40010800)
|
|
||||||
/** GPIO port B register map base pointer */
|
|
||||||
#define GPIOB_BASE ((struct gpio_reg_map*)0x40010C00)
|
|
||||||
/** GPIO port C register map base pointer */
|
|
||||||
#define GPIOC_BASE ((struct gpio_reg_map*)0x40011000)
|
|
||||||
/** GPIO port D register map base pointer */
|
|
||||||
#define GPIOD_BASE ((struct gpio_reg_map*)0x40011400)
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
|
||||||
/** GPIO port E register map base pointer */
|
|
||||||
#define GPIOE_BASE ((struct gpio_reg_map*)0x40011800)
|
|
||||||
/** GPIO port F register map base pointer */
|
|
||||||
#define GPIOF_BASE ((struct gpio_reg_map*)0x40011C00)
|
|
||||||
/** GPIO port G register map base pointer */
|
|
||||||
#define GPIOG_BASE ((struct gpio_reg_map*)0x40012000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO register bit definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Control registers, low and high */
|
|
||||||
|
|
||||||
#define GPIO_CR_CNF (0x3 << 2)
|
|
||||||
#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2)
|
|
||||||
#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2)
|
|
||||||
#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2)
|
|
||||||
#define GPIO_CR_CNF_OUTPUT_PP (0x0 << 2)
|
|
||||||
#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2)
|
|
||||||
#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2)
|
|
||||||
#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2)
|
|
||||||
#define GPIO_CR_MODE 0x3
|
|
||||||
#define GPIO_CR_MODE_INPUT 0x0
|
|
||||||
#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1
|
|
||||||
#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2
|
|
||||||
#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief GPIO Pin modes.
|
|
||||||
*
|
|
||||||
* These only allow for 50MHZ max output speeds; if you want slower,
|
|
||||||
* use direct register access.
|
|
||||||
*/
|
|
||||||
typedef enum gpio_pin_mode {
|
|
||||||
GPIO_OUTPUT_PP = (GPIO_CR_CNF_OUTPUT_PP |
|
|
||||||
GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output push-pull. */
|
|
||||||
GPIO_OUTPUT_OD = (GPIO_CR_CNF_OUTPUT_OD |
|
|
||||||
GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output open-drain. */
|
|
||||||
GPIO_AF_OUTPUT_PP = (GPIO_CR_CNF_AF_OUTPUT_PP |
|
|
||||||
GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function
|
|
||||||
output push-pull. */
|
|
||||||
GPIO_AF_OUTPUT_OD = (GPIO_CR_CNF_AF_OUTPUT_OD |
|
|
||||||
GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function
|
|
||||||
output open drain. */
|
|
||||||
GPIO_INPUT_ANALOG = (GPIO_CR_CNF_INPUT_ANALOG |
|
|
||||||
GPIO_CR_MODE_INPUT), /**< Analog input. */
|
|
||||||
GPIO_INPUT_FLOATING = (GPIO_CR_CNF_INPUT_FLOATING |
|
|
||||||
GPIO_CR_MODE_INPUT), /**< Input floating. */
|
|
||||||
GPIO_INPUT_PD = (GPIO_CR_CNF_INPUT_PU_PD |
|
|
||||||
GPIO_CR_MODE_INPUT), /**< Input pull-down. */
|
|
||||||
GPIO_AF_INPUT_PD = (GPIO_INPUT_PD), /**< Input pull-down. */
|
|
||||||
GPIO_INPUT_PU /**< Input pull-up. */
|
|
||||||
|
|
||||||
|
|
||||||
/* GPIO_INPUT_PU treated as a special case, for ODR twiddling */
|
|
||||||
} gpio_pin_mode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO Convenience routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gpio_init(gpio_dev *dev);
|
|
||||||
void gpio_init_all(void);
|
|
||||||
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a GPIO port's corresponding afio_exti_port.
|
|
||||||
* @param dev GPIO device whose afio_exti_port to return.
|
|
||||||
*/
|
|
||||||
static inline afio_exti_port gpio_exti_port(gpio_dev *dev) {
|
|
||||||
return dev->exti_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set or reset a GPIO pin.
|
|
||||||
*
|
|
||||||
* Pin must have previously been configured to output mode.
|
|
||||||
*
|
|
||||||
* @param dev GPIO device whose pin to set.
|
|
||||||
* @param pin Pin on to set or reset
|
|
||||||
* @param val If true, set the pin. If false, reset the pin.
|
|
||||||
*/
|
|
||||||
static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
|
|
||||||
if (val) {
|
|
||||||
dev->regs->BSRR = BIT(pin);
|
|
||||||
} else {
|
|
||||||
dev->regs->BRR = BIT(pin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether or not a GPIO pin is set.
|
|
||||||
*
|
|
||||||
* Pin must have previously been configured to input mode.
|
|
||||||
*
|
|
||||||
* @param dev GPIO device whose pin to test.
|
|
||||||
* @param pin Pin on dev to test.
|
|
||||||
* @return True if the pin is set, false otherwise.
|
|
||||||
*/
|
|
||||||
static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
|
|
||||||
return dev->regs->IDR & BIT(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle a pin configured as output push-pull.
|
|
||||||
* @param dev GPIO device.
|
|
||||||
* @param pin Pin on dev to toggle.
|
|
||||||
*/
|
|
||||||
static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
|
|
||||||
dev->regs->ODR = dev->regs->ODR ^ BIT(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AFIO register map
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** AFIO register map */
|
|
||||||
typedef struct afio_reg_map {
|
|
||||||
__io uint32 EVCR; /**< Event control register. */
|
|
||||||
__io uint32 MAPR; /**< AF remap and debug I/O configuration
|
|
||||||
register. */
|
|
||||||
__io uint32 EXTICR1; /**< External interrupt configuration
|
|
||||||
register 1. */
|
|
||||||
__io uint32 EXTICR2; /**< External interrupt configuration
|
|
||||||
register 2. */
|
|
||||||
__io uint32 EXTICR3; /**< External interrupt configuration
|
|
||||||
register 3. */
|
|
||||||
__io uint32 EXTICR4; /**< External interrupt configuration
|
|
||||||
register 4. */
|
|
||||||
__io uint32 MAPR2; /**< AF remap and debug I/O configuration
|
|
||||||
register 2. */
|
|
||||||
} afio_reg_map;
|
|
||||||
|
|
||||||
/** AFIO register map base pointer. */
|
|
||||||
#define AFIO_BASE ((struct afio_reg_map *)0x40010000)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AFIO register bit definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Event control register */
|
|
||||||
|
|
||||||
#define AFIO_EVCR_EVOE (0x1 << 7)
|
|
||||||
#define AFIO_EVCR_PORT_PA (0x0 << 4)
|
|
||||||
#define AFIO_EVCR_PORT_PB (0x1 << 4)
|
|
||||||
#define AFIO_EVCR_PORT_PC (0x2 << 4)
|
|
||||||
#define AFIO_EVCR_PORT_PD (0x3 << 4)
|
|
||||||
#define AFIO_EVCR_PORT_PE (0x4 << 4)
|
|
||||||
#define AFIO_EVCR_PIN_0 0x0
|
|
||||||
#define AFIO_EVCR_PIN_1 0x1
|
|
||||||
#define AFIO_EVCR_PIN_2 0x2
|
|
||||||
#define AFIO_EVCR_PIN_3 0x3
|
|
||||||
#define AFIO_EVCR_PIN_4 0x4
|
|
||||||
#define AFIO_EVCR_PIN_5 0x5
|
|
||||||
#define AFIO_EVCR_PIN_6 0x6
|
|
||||||
#define AFIO_EVCR_PIN_7 0x7
|
|
||||||
#define AFIO_EVCR_PIN_8 0x8
|
|
||||||
#define AFIO_EVCR_PIN_9 0x9
|
|
||||||
#define AFIO_EVCR_PIN_10 0xA
|
|
||||||
#define AFIO_EVCR_PIN_11 0xB
|
|
||||||
#define AFIO_EVCR_PIN_12 0xC
|
|
||||||
#define AFIO_EVCR_PIN_13 0xD
|
|
||||||
#define AFIO_EVCR_PIN_14 0xE
|
|
||||||
#define AFIO_EVCR_PIN_15 0xF
|
|
||||||
|
|
||||||
/* AF remap and debug I/O configuration register */
|
|
||||||
|
|
||||||
#define AFIO_MAPR_SWJ_CFG (0x7 << 24)
|
|
||||||
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24)
|
|
||||||
#define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24)
|
|
||||||
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24)
|
|
||||||
#define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24)
|
|
||||||
#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20)
|
|
||||||
#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19)
|
|
||||||
#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18)
|
|
||||||
#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17)
|
|
||||||
#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16)
|
|
||||||
#define AFIO_MAPR_PD01_REMAP BIT(15)
|
|
||||||
#define AFIO_MAPR_CAN_REMAP (0x3 << 13)
|
|
||||||
#define AFIO_MAPR_CAN_REMAP_NONE (0x0 << 13)
|
|
||||||
#define AFIO_MAPR_CAN_REMAP_PB8_PB9 (0x2 << 13)
|
|
||||||
#define AFIO_MAPR_CAN_REMAP_PD0_PD1 (0x3 << 13)
|
|
||||||
#define AFIO_MAPR_TIM4_REMAP BIT(12)
|
|
||||||
#define AFIO_MAPR_TIM3_REMAP (0x3 << 10)
|
|
||||||
#define AFIO_MAPR_TIM3_REMAP_NONE (0x0 << 10)
|
|
||||||
#define AFIO_MAPR_TIM3_REMAP_PARTIAL (0x2 << 10)
|
|
||||||
#define AFIO_MAPR_TIM3_REMAP_FULL (0x3 << 10)
|
|
||||||
#define AFIO_MAPR_TIM2_REMAP (0x3 << 8)
|
|
||||||
#define AFIO_MAPR_TIM2_REMAP_NONE (0x0 << 8)
|
|
||||||
#define AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3 (0x1 << 8)
|
|
||||||
#define AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11 (0x2 << 8)
|
|
||||||
#define AFIO_MAPR_TIM2_REMAP_FULL (0x3 << 8)
|
|
||||||
#define AFIO_MAPR_TIM1_REMAP (0x3 << 6)
|
|
||||||
#define AFIO_MAPR_TIM1_REMAP_NONE (0x0 << 6)
|
|
||||||
#define AFIO_MAPR_TIM1_REMAP_PARTIAL (0x1 << 6)
|
|
||||||
#define AFIO_MAPR_TIM1_REMAP_FULL (0x3 << 6)
|
|
||||||
#define AFIO_MAPR_USART3_REMAP (0x3 << 4)
|
|
||||||
#define AFIO_MAPR_USART3_REMAP_NONE (0x0 << 4)
|
|
||||||
#define AFIO_MAPR_USART3_REMAP_PARTIAL (0x1 << 4)
|
|
||||||
#define AFIO_MAPR_USART3_REMAP_FULL (0x3 << 4)
|
|
||||||
#define AFIO_MAPR_USART2_REMAP BIT(3)
|
|
||||||
#define AFIO_MAPR_USART1_REMAP BIT(2)
|
|
||||||
#define AFIO_MAPR_I2C1_REMAP BIT(1)
|
|
||||||
#define AFIO_MAPR_SPI1_REMAP BIT(0)
|
|
||||||
|
|
||||||
/* External interrupt configuration register 1 */
|
|
||||||
|
|
||||||
#define AFIO_EXTICR1_EXTI3 (0xF << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PA (0x0 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PB (0x1 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PC (0x2 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PD (0x3 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PE (0x4 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PF (0x5 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI3_PG (0x6 << 12)
|
|
||||||
#define AFIO_EXTICR1_EXTI2 (0xF << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PA (0x0 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PB (0x1 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PC (0x2 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PD (0x3 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PE (0x4 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PF (0x5 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI2_PG (0x6 << 8)
|
|
||||||
#define AFIO_EXTICR1_EXTI1 (0xF << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PA (0x0 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PB (0x1 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PC (0x2 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PD (0x3 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PE (0x4 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PF (0x5 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI1_PG (0x6 << 4)
|
|
||||||
#define AFIO_EXTICR1_EXTI0 0xF
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PA 0x0
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PB 0x1
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PC 0x2
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PD 0x3
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PE 0x4
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PF 0x5
|
|
||||||
#define AFIO_EXTICR1_EXTI0_PG 0x6
|
|
||||||
|
|
||||||
/* External interrupt configuration register 2 */
|
|
||||||
|
|
||||||
#define AFIO_EXTICR2_EXTI7 (0xF << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PA (0x0 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PB (0x1 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PC (0x2 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PD (0x3 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PE (0x4 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PF (0x5 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI7_PG (0x6 << 12)
|
|
||||||
#define AFIO_EXTICR2_EXTI6 (0xF << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PA (0x0 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PB (0x1 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PC (0x2 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PD (0x3 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PE (0x4 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PF (0x5 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI6_PG (0x6 << 8)
|
|
||||||
#define AFIO_EXTICR2_EXTI5 (0xF << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PA (0x0 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PB (0x1 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PC (0x2 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PD (0x3 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PE (0x4 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PF (0x5 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI5_PG (0x6 << 4)
|
|
||||||
#define AFIO_EXTICR2_EXTI4 0xF
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PA 0x0
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PB 0x1
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PC 0x2
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PD 0x3
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PE 0x4
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PF 0x5
|
|
||||||
#define AFIO_EXTICR2_EXTI4_PG 0x6
|
|
||||||
|
|
||||||
/* AF remap and debug I/O configuration register 2 */
|
|
||||||
|
|
||||||
#define AFIO_MAPR2_FSMC_NADV BIT(10)
|
|
||||||
#define AFIO_MAPR2_TIM14_REMAP BIT(9)
|
|
||||||
#define AFIO_MAPR2_TIM13_REMAP BIT(8)
|
|
||||||
#define AFIO_MAPR2_TIM11_REMAP BIT(7)
|
|
||||||
#define AFIO_MAPR2_TIM10_REMAP BIT(6)
|
|
||||||
#define AFIO_MAPR2_TIM9_REMAP BIT(5)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AFIO convenience routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
void afio_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* External interrupt line numbers.
|
|
||||||
*/
|
|
||||||
typedef enum afio_exti_num {
|
|
||||||
AFIO_EXTI_0, /**< External interrupt line 0. */
|
|
||||||
AFIO_EXTI_1, /**< External interrupt line 1. */
|
|
||||||
AFIO_EXTI_2, /**< External interrupt line 2. */
|
|
||||||
AFIO_EXTI_3, /**< External interrupt line 3. */
|
|
||||||
AFIO_EXTI_4, /**< External interrupt line 4. */
|
|
||||||
AFIO_EXTI_5, /**< External interrupt line 5. */
|
|
||||||
AFIO_EXTI_6, /**< External interrupt line 6. */
|
|
||||||
AFIO_EXTI_7, /**< External interrupt line 7. */
|
|
||||||
AFIO_EXTI_8, /**< External interrupt line 8. */
|
|
||||||
AFIO_EXTI_9, /**< External interrupt line 9. */
|
|
||||||
AFIO_EXTI_10, /**< External interrupt line 10. */
|
|
||||||
AFIO_EXTI_11, /**< External interrupt line 11. */
|
|
||||||
AFIO_EXTI_12, /**< External interrupt line 12. */
|
|
||||||
AFIO_EXTI_13, /**< External interrupt line 13. */
|
|
||||||
AFIO_EXTI_14, /**< External interrupt line 14. */
|
|
||||||
AFIO_EXTI_15, /**< External interrupt line 15. */
|
|
||||||
} afio_exti_num;
|
|
||||||
|
|
||||||
void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port);
|
|
||||||
|
|
||||||
/* HACK: Use upper bit to denote MAPR2, Bit 31 is reserved and
|
|
||||||
* not used in either MAPR or MAPR2 */
|
|
||||||
#define AFIO_REMAP_USE_MAPR2 (1 << 31)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Available peripheral remaps.
|
|
||||||
* @see afio_remap()
|
|
||||||
*/
|
|
||||||
typedef enum afio_remap_peripheral {
|
|
||||||
AFIO_REMAP_ADC2_ETRGREG = AFIO_MAPR_ADC2_ETRGREG_REMAP, /**<
|
|
||||||
ADC 2 external trigger regular conversion remapping */
|
|
||||||
AFIO_REMAP_ADC2_ETRGINJ = AFIO_MAPR_ADC2_ETRGINJ_REMAP, /**<
|
|
||||||
ADC 2 external trigger injected conversion remapping */
|
|
||||||
AFIO_REMAP_ADC1_ETRGREG = AFIO_MAPR_ADC1_ETRGREG_REMAP, /**<
|
|
||||||
ADC 1 external trigger regular conversion remapping */
|
|
||||||
AFIO_REMAP_ADC1_ETRGINJ = AFIO_MAPR_ADC1_ETRGINJ_REMAP, /**<
|
|
||||||
ADC 1 external trigger injected conversion remapping */
|
|
||||||
AFIO_REMAP_TIM5CH4_I = AFIO_MAPR_TIM5CH4_IREMAP, /**<
|
|
||||||
Timer 5 channel 4 internal remapping */
|
|
||||||
AFIO_REMAP_PD01 = AFIO_MAPR_PD01_REMAP, /**<
|
|
||||||
Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
|
|
||||||
AFIO_REMAP_CAN_1 = AFIO_MAPR_CAN_REMAP_PB8_PB9, /**<
|
|
||||||
CAN alternate function remapping 1 (RX on PB8, TX on PB9) */
|
|
||||||
AFIO_REMAP_CAN_2 = AFIO_MAPR_CAN_REMAP_PD0_PD1, /**<
|
|
||||||
CAN alternate function remapping 2 (RX on PD0, TX on PD1) */
|
|
||||||
AFIO_REMAP_TIM4 = AFIO_MAPR_TIM4_REMAP, /**<
|
|
||||||
Timer 4 remapping */
|
|
||||||
AFIO_REMAP_TIM3_PARTIAL = AFIO_MAPR_TIM3_REMAP_PARTIAL, /**<
|
|
||||||
Timer 3 partial remapping */
|
|
||||||
AFIO_REMAP_TIM3_FULL = AFIO_MAPR_TIM3_REMAP_FULL, /**<
|
|
||||||
Timer 3 full remapping */
|
|
||||||
AFIO_REMAP_TIM2_PARTIAL_1 = AFIO_MAPR_TIM2_REMAP_PA15_PB3_PA2_PA3, /**<
|
|
||||||
Timer 2 partial remapping 1 (CH1 and ETR on PA15, CH2 on PB3, CH3
|
|
||||||
on PA2, CH4 on PA3) */
|
|
||||||
AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11, /**<
|
|
||||||
Timer 2 partial remapping 2 (CH1 and ETR on PA0, CH2 on PA1, CH3
|
|
||||||
on PB10, CH4 on PB11) */
|
|
||||||
AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL, /**<
|
|
||||||
Timer 2 full remapping */
|
|
||||||
AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP, /**<
|
|
||||||
USART 2 remapping */
|
|
||||||
AFIO_REMAP_USART1 = AFIO_MAPR_USART1_REMAP, /**<
|
|
||||||
USART 1 remapping */
|
|
||||||
AFIO_REMAP_I2C1 = AFIO_MAPR_I2C1_REMAP, /**<
|
|
||||||
I2C 1 remapping */
|
|
||||||
AFIO_REMAP_SPI1 = AFIO_MAPR_SPI1_REMAP, /**<
|
|
||||||
SPI 1 remapping */
|
|
||||||
AFIO_REMAP_FSMC_NADV = (AFIO_MAPR2_FSMC_NADV |
|
|
||||||
AFIO_REMAP_USE_MAPR2), /**<
|
|
||||||
NADV signal not connected */
|
|
||||||
AFIO_REMAP_TIM14 = (AFIO_MAPR2_TIM14_REMAP |
|
|
||||||
AFIO_REMAP_USE_MAPR2), /**<
|
|
||||||
Timer 14 remapping */
|
|
||||||
AFIO_REMAP_TIM13 = (AFIO_MAPR2_TIM13_REMAP |
|
|
||||||
AFIO_REMAP_USE_MAPR2), /**<
|
|
||||||
Timer 13 remapping */
|
|
||||||
AFIO_REMAP_TIM11 = (AFIO_MAPR2_TIM11_REMAP |
|
|
||||||
AFIO_REMAP_USE_MAPR2), /**<
|
|
||||||
Timer 11 remapping */
|
|
||||||
AFIO_REMAP_TIM10 = (AFIO_MAPR2_TIM10_REMAP |
|
|
||||||
AFIO_REMAP_USE_MAPR2), /**<
|
|
||||||
Timer 10 remapping */
|
|
||||||
AFIO_REMAP_TIM9 = (AFIO_MAPR2_TIM9_REMAP |
|
|
||||||
AFIO_REMAP_USE_MAPR2) /**<
|
|
||||||
Timer 9 */
|
|
||||||
} afio_remap_peripheral;
|
|
||||||
|
|
||||||
void afio_remap(afio_remap_peripheral p);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Debug port configuration
|
|
||||||
*
|
|
||||||
* Used to configure the behavior of JTAG and Serial Wire (SW) debug
|
|
||||||
* ports and their associated GPIO pins.
|
|
||||||
*
|
|
||||||
* @see afio_cfg_debug_ports()
|
|
||||||
*/
|
|
||||||
typedef enum afio_debug_cfg {
|
|
||||||
AFIO_DEBUG_FULL_SWJ = AFIO_MAPR_SWJ_CFG_FULL_SWJ, /**<
|
|
||||||
Full Serial Wire and JTAG debug */
|
|
||||||
AFIO_DEBUG_FULL_SWJ_NO_NJRST = AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST, /**<
|
|
||||||
Full Serial Wire and JTAG, but no NJTRST. */
|
|
||||||
AFIO_DEBUG_SW_ONLY = AFIO_MAPR_SWJ_CFG_NO_JTAG_SW, /**<
|
|
||||||
Serial Wire debug only (JTAG-DP disabled,
|
|
||||||
SW-DP enabled) */
|
|
||||||
AFIO_DEBUG_NONE = AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW /**<
|
|
||||||
No debug; all JTAG and SW pins are free
|
|
||||||
for use as GPIOs. */
|
|
||||||
} afio_debug_cfg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable or disable the JTAG and SW debug ports.
|
|
||||||
* @param config Desired debug port configuration
|
|
||||||
* @see afio_debug_cfg
|
|
||||||
*/
|
|
||||||
static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
|
|
||||||
__io uint32 *mapr = &AFIO_BASE->MAPR;
|
|
||||||
*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifdef STM32F2
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file gpio.c
|
* @file gpio.c
|
||||||
* @brief GPIO initialization routine
|
* @brief GPIO initialization routine
|
||||||
|
@ -38,62 +36,57 @@
|
||||||
* GPIO devices
|
* GPIO devices
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gpio_dev gpioa = {
|
/** GPIO port A device. */
|
||||||
|
const gpio_dev GPIOA = {
|
||||||
.regs = GPIOA_BASE,
|
.regs = GPIOA_BASE,
|
||||||
.clk_id = RCC_GPIOA,
|
.clk_id = RCC_GPIOA,
|
||||||
.exti_port = AFIO_EXTI_PA,
|
.exti_port = AFIO_EXTI_PA,
|
||||||
};
|
};
|
||||||
/** GPIO port A device. */
|
|
||||||
gpio_dev* const GPIOA = &gpioa;
|
|
||||||
|
|
||||||
gpio_dev gpiob = {
|
/** GPIO port B device. */
|
||||||
|
const gpio_dev GPIOB = {
|
||||||
.regs = GPIOB_BASE,
|
.regs = GPIOB_BASE,
|
||||||
.clk_id = RCC_GPIOB,
|
.clk_id = RCC_GPIOB,
|
||||||
.exti_port = AFIO_EXTI_PB,
|
.exti_port = AFIO_EXTI_PB,
|
||||||
};
|
};
|
||||||
/** GPIO port B device. */
|
|
||||||
gpio_dev* const GPIOB = &gpiob;
|
|
||||||
|
|
||||||
gpio_dev gpioc = {
|
/** GPIO port C device. */
|
||||||
|
const gpio_dev GPIOC = {
|
||||||
.regs = GPIOC_BASE,
|
.regs = GPIOC_BASE,
|
||||||
.clk_id = RCC_GPIOC,
|
.clk_id = RCC_GPIOC,
|
||||||
.exti_port = AFIO_EXTI_PC,
|
.exti_port = AFIO_EXTI_PC,
|
||||||
};
|
};
|
||||||
/** GPIO port C device. */
|
|
||||||
gpio_dev* const GPIOC = &gpioc;
|
|
||||||
|
|
||||||
gpio_dev gpiod = {
|
/** GPIO port D device. */
|
||||||
|
const gpio_dev GPIOD = {
|
||||||
.regs = GPIOD_BASE,
|
.regs = GPIOD_BASE,
|
||||||
.clk_id = RCC_GPIOD,
|
.clk_id = RCC_GPIOD,
|
||||||
.exti_port = AFIO_EXTI_PD,
|
.exti_port = AFIO_EXTI_PD,
|
||||||
};
|
};
|
||||||
/** GPIO port D device. */
|
|
||||||
gpio_dev* const GPIOD = &gpiod;
|
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
gpio_dev gpioe = {
|
/** GPIO port E device. */
|
||||||
|
const gpio_dev GPIOE = {
|
||||||
.regs = GPIOE_BASE,
|
.regs = GPIOE_BASE,
|
||||||
.clk_id = RCC_GPIOE,
|
.clk_id = RCC_GPIOE,
|
||||||
.exti_port = AFIO_EXTI_PE,
|
.exti_port = AFIO_EXTI_PE,
|
||||||
};
|
};
|
||||||
/** GPIO port E device. */
|
|
||||||
gpio_dev* const GPIOE = &gpioe;
|
|
||||||
|
|
||||||
gpio_dev gpiof = {
|
#if 0 // not available on LQFP 100 package
|
||||||
|
/** GPIO port F device. */
|
||||||
|
const gpio_dev GPIOF = {
|
||||||
.regs = GPIOF_BASE,
|
.regs = GPIOF_BASE,
|
||||||
.clk_id = RCC_GPIOF,
|
.clk_id = RCC_GPIOF,
|
||||||
.exti_port = AFIO_EXTI_PF,
|
.exti_port = AFIO_EXTI_PF,
|
||||||
};
|
};
|
||||||
/** GPIO port F device. */
|
|
||||||
gpio_dev* const GPIOF = &gpiof;
|
|
||||||
|
|
||||||
gpio_dev gpiog = {
|
/** GPIO port G device. */
|
||||||
|
const gpio_dev GPIOG = {
|
||||||
.regs = GPIOG_BASE,
|
.regs = GPIOG_BASE,
|
||||||
.clk_id = RCC_GPIOG,
|
.clk_id = RCC_GPIOG,
|
||||||
.exti_port = AFIO_EXTI_PG,
|
.exti_port = AFIO_EXTI_PG,
|
||||||
};
|
};
|
||||||
/** GPIO port G device. */
|
#endif
|
||||||
gpio_dev* const GPIOG = &gpiog;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,7 +100,7 @@ gpio_dev* const GPIOG = &gpiog;
|
||||||
*
|
*
|
||||||
* @param dev GPIO device to initialize.
|
* @param dev GPIO device to initialize.
|
||||||
*/
|
*/
|
||||||
void gpio_init(gpio_dev *dev) {
|
void gpio_init(const gpio_dev *dev) {
|
||||||
rcc_clk_enable(dev->clk_id);
|
rcc_clk_enable(dev->clk_id);
|
||||||
rcc_reset_dev(dev->clk_id);
|
rcc_reset_dev(dev->clk_id);
|
||||||
}
|
}
|
||||||
|
@ -116,27 +109,29 @@ void gpio_init(gpio_dev *dev) {
|
||||||
* Initialize and reset all available GPIO devices.
|
* Initialize and reset all available GPIO devices.
|
||||||
*/
|
*/
|
||||||
void gpio_init_all(void) {
|
void gpio_init_all(void) {
|
||||||
gpio_init(GPIOA);
|
gpio_init(&GPIOA);
|
||||||
gpio_init(GPIOB);
|
gpio_init(&GPIOB);
|
||||||
gpio_init(GPIOC);
|
gpio_init(&GPIOC);
|
||||||
gpio_init(GPIOD);
|
gpio_init(&GPIOD);
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
gpio_init(GPIOE);
|
gpio_init(&GPIOE);
|
||||||
gpio_init(GPIOF);
|
#if 0 // not available on LQFP 100 package
|
||||||
gpio_init(GPIOG);
|
gpio_init(GPIOF);
|
||||||
|
gpio_init(GPIOG);
|
||||||
|
#endif // not available on LQFP 100 package
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARDUINO_STM32F4_NETDUINO2PLUS
|
#ifdef ARDUINO_STM32F4_NETDUINO2PLUS
|
||||||
// PA8 Output the Master Clock MCO1
|
// PA8 Output the Master Clock MCO1
|
||||||
gpio_set_af_mode(GPIOA, 8, 0);
|
gpio_set_af_mode(PA8, 0);
|
||||||
gpio_set_mode(GPIOA, 8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
gpio_set_mode(PA8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
||||||
// PB4 as alternate MISO Input
|
// PB4 as alternate MISO Input
|
||||||
gpio_set_af_mode(GPIOB, 4, 5);
|
gpio_set_af_mode(PB4, 5);
|
||||||
// PA5 as alternate SCK Output
|
// PA5 as alternate SCK Output
|
||||||
gpio_set_af_mode(GPIOA, 5, 5);
|
gpio_set_af_mode(PA5, 5);
|
||||||
// PA7 as alternate MOSI Output
|
// PA7 as alternate MOSI Output
|
||||||
gpio_set_af_mode(GPIOA, 7, 5);
|
gpio_set_af_mode(PA7, 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,16 +143,17 @@ void gpio_init_all(void) {
|
||||||
* @param mode General purpose or alternate function mode to set the pin to.
|
* @param mode General purpose or alternate function mode to set the pin to.
|
||||||
* @see gpio_pin_mode
|
* @see gpio_pin_mode
|
||||||
*/
|
*/
|
||||||
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
|
void gpio_set_mode(uint8_t io_pin, gpio_pin_mode mode) {
|
||||||
gpio_reg_map *regs = dev->regs;
|
gpio_reg_map *regs = (PIN_MAP[io_pin].gpio_device)->regs;
|
||||||
|
uint8_t pin = io_pin&0x0f;
|
||||||
|
|
||||||
//regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7)));
|
//regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 8) & 15) << (4*(pin&7)));
|
||||||
//gpio_set_af_mode(dev, pin, mode>>8);
|
//gpio_set_af_mode(dev, pin, mode>>8);
|
||||||
|
|
||||||
regs->MODER = (regs->MODER & ~( 3 << (2*pin))) | (((mode >> 0) & 3) << (2*pin));
|
regs->MODER = (regs->MODER & ~( 3 << (pin<<1))) | (((mode >> 0) & 3) << (pin<<1));
|
||||||
regs->PUPDR = (regs->PUPDR & ~( 3 << (2*pin))) | (((mode >> 2) & 3) << (2*pin));
|
regs->PUPDR = (regs->PUPDR & ~( 3 << (pin<<1))) | (((mode >> 2) & 3) << (pin<<1));
|
||||||
regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (2*pin))) | (((mode >> 4) & 3) << (2*pin));
|
regs->OSPEEDR = (regs->OSPEEDR & ~( 3 << (pin<<1))) | (((mode >> 4) & 3) << (pin<<1));
|
||||||
regs->OTYPER = (regs->OTYPER & ~( 1 << (1*pin))) | (((mode >> 6) & 1) << (1*pin));
|
regs->OTYPER = (regs->OTYPER & ~( 1 << (pin<<0))) | (((mode >> 6) & 1) << (pin<<0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,10 +164,11 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
|
||||||
* @param mode alternate function mode to set the pin to.
|
* @param mode alternate function mode to set the pin to.
|
||||||
* @see gpio_pin_mode
|
* @see gpio_pin_mode
|
||||||
*/
|
*/
|
||||||
void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode) {
|
void gpio_set_af_mode(uint8_t io_pin, int mode) {
|
||||||
gpio_reg_map *regs = dev->regs;
|
gpio_reg_map *regs = (PIN_MAP[io_pin].gpio_device)->regs;
|
||||||
|
uint8_t pin = io_pin&0x0F;
|
||||||
|
|
||||||
regs->AFR[pin/8] = (regs->AFR[pin/8] & ~(15 << (4*(pin&7)))) | (((mode >> 0) & 15) << (4*(pin&7)));
|
regs->AFR[pin>>3] = (regs->AFR[pin>>3] & ~(15 << ((pin&7)<<2))) | (((mode >> 0) & 15) << ((pin&7)<<2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -220,5 +217,3 @@ void afio_remap(afio_remap_peripheral remapping) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
|
@ -31,8 +31,8 @@
|
||||||
* (AFIO) prototypes, defines, and inlined access functions.
|
* (AFIO) prototypes, defines, and inlined access functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GPIO_H_
|
#ifndef _GPIO_DEF_H_
|
||||||
#define _GPIO_H_
|
#define _GPIO_DEF_H_
|
||||||
|
|
||||||
#include "libmaple.h"
|
#include "libmaple.h"
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
|
@ -74,11 +74,14 @@ typedef enum afio_exti_port {
|
||||||
AFIO_EXTI_PD, /**< Use port D (PDx) pin. */
|
AFIO_EXTI_PD, /**< Use port D (PDx) pin. */
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
AFIO_EXTI_PE, /**< Use port E (PEx) pin. */
|
AFIO_EXTI_PE, /**< Use port E (PEx) pin. */
|
||||||
|
#if 0 // not available on LQFP 100 package
|
||||||
AFIO_EXTI_PF, /**< Use port F (PFx) pin. */
|
AFIO_EXTI_PF, /**< Use port F (PFx) pin. */
|
||||||
AFIO_EXTI_PG, /**< Use port G (PGx) pin. */
|
AFIO_EXTI_PG, /**< Use port G (PGx) pin. */
|
||||||
|
#endif // not available on LQFP 100 package
|
||||||
#endif
|
#endif
|
||||||
} afio_exti_port;
|
} afio_exti_port;
|
||||||
|
|
||||||
|
|
||||||
/** GPIO device type */
|
/** GPIO device type */
|
||||||
typedef struct gpio_dev {
|
typedef struct gpio_dev {
|
||||||
gpio_reg_map *regs; /**< Register map */
|
gpio_reg_map *regs; /**< Register map */
|
||||||
|
@ -86,21 +89,18 @@ typedef struct gpio_dev {
|
||||||
afio_exti_port exti_port; /**< AFIO external interrupt port value */
|
afio_exti_port exti_port; /**< AFIO external interrupt port value */
|
||||||
} gpio_dev;
|
} gpio_dev;
|
||||||
|
|
||||||
extern gpio_dev gpioa;
|
extern const gpio_dev GPIOA;
|
||||||
extern gpio_dev* const GPIOA;
|
extern const gpio_dev GPIOB;
|
||||||
extern gpio_dev gpiob;
|
extern const gpio_dev GPIOC;
|
||||||
extern gpio_dev* const GPIOB;
|
extern const gpio_dev GPIOD;
|
||||||
extern gpio_dev gpioc;
|
|
||||||
extern gpio_dev* const GPIOC;
|
|
||||||
extern gpio_dev gpiod;
|
|
||||||
extern gpio_dev* const GPIOD;
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
extern gpio_dev gpioe;
|
extern const gpio_dev GPIOE;
|
||||||
extern gpio_dev* const GPIOE;
|
#if 0 // not available on LQFP 100 package
|
||||||
extern gpio_dev gpiof;
|
extern gpio_dev gpiof;
|
||||||
extern gpio_dev* const GPIOF;
|
extern gpio_dev* const GPIOF;
|
||||||
extern gpio_dev gpiog;
|
extern gpio_dev gpiog;
|
||||||
extern gpio_dev* const GPIOG;
|
extern gpio_dev* const GPIOG;
|
||||||
|
#endif // not available on LQFP 100 package
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** GPIO port register map base pointer */
|
/** GPIO port register map base pointer */
|
||||||
|
@ -110,8 +110,10 @@ extern gpio_dev* const GPIOG;
|
||||||
#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00)
|
#define GPIOD_BASE ((struct gpio_reg_map*)0x40020C00)
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000)
|
#define GPIOE_BASE ((struct gpio_reg_map*)0x40021000)
|
||||||
|
#if 0 // not available on LQFP 100 package
|
||||||
#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400)
|
#define GPIOF_BASE ((struct gpio_reg_map*)0x40021400)
|
||||||
#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800)
|
#define GPIOG_BASE ((struct gpio_reg_map*)0x40021800)
|
||||||
|
#endif // not available on LQFP 100 package
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -190,61 +192,6 @@ typedef enum gpio_pin_mode {
|
||||||
GPIO_BIGNUMBER = 0xfff
|
GPIO_BIGNUMBER = 0xfff
|
||||||
} gpio_pin_mode;
|
} gpio_pin_mode;
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO Convenience routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gpio_init(gpio_dev *dev);
|
|
||||||
void gpio_init_all(void);
|
|
||||||
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
|
|
||||||
void gpio_set_af_mode(gpio_dev *dev, uint8 pin, int mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a GPIO port's corresponding afio_exti_port.
|
|
||||||
* @param dev GPIO device whose afio_exti_port to return.
|
|
||||||
*/
|
|
||||||
static inline afio_exti_port gpio_exti_port(gpio_dev *dev) {
|
|
||||||
return dev->exti_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set or reset a GPIO pin.
|
|
||||||
*
|
|
||||||
* Pin must have previously been configured to output mode.
|
|
||||||
*
|
|
||||||
* @param dev GPIO device whose pin to set.
|
|
||||||
* @param pin Pin on to set or reset
|
|
||||||
* @param val If true, set the pin. If false, reset the pin.
|
|
||||||
*/
|
|
||||||
static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
|
|
||||||
if (val) {
|
|
||||||
dev->regs->BSRRL = BIT(pin);
|
|
||||||
} else {
|
|
||||||
dev->regs->BSRRH = BIT(pin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether or not a GPIO pin is set.
|
|
||||||
*
|
|
||||||
* Pin must have previously been configured to input mode.
|
|
||||||
*
|
|
||||||
* @param dev GPIO device whose pin to test.
|
|
||||||
* @param pin Pin on dev to test.
|
|
||||||
* @return True if the pin is set, false otherwise.
|
|
||||||
*/
|
|
||||||
static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) {
|
|
||||||
return dev->regs->IDR & BIT(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggle a pin configured as output push-pull.
|
|
||||||
* @param dev GPIO device.
|
|
||||||
* @param pin Pin on dev to toggle.
|
|
||||||
*/
|
|
||||||
static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
|
|
||||||
dev->regs->ODR = dev->regs->ODR ^ BIT(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AFIO register map
|
* AFIO register map
|
||||||
|
@ -532,15 +479,6 @@ typedef enum afio_debug_cfg {
|
||||||
for use as GPIOs. */
|
for use as GPIOs. */
|
||||||
} afio_debug_cfg;
|
} afio_debug_cfg;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable or disable the JTAG and SW debug ports.
|
|
||||||
* @param config Desired debug port configuration
|
|
||||||
* @see afio_debug_cfg
|
|
||||||
*/
|
|
||||||
static inline void afio_cfg_debug_ports(afio_debug_cfg config) {
|
|
||||||
//__io uint32 *mapr = &AFIO_BASE->MAPR;
|
|
||||||
//*mapr = (*mapr & ~AFIO_MAPR_SWJ_CFG) | config;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -41,9 +41,9 @@
|
||||||
|
|
||||||
static i2c_dev i2c_dev1 = {
|
static i2c_dev i2c_dev1 = {
|
||||||
.regs = I2C1_BASE,
|
.regs = I2C1_BASE,
|
||||||
.gpio_port = &gpiob,
|
//.gpio_port = &gpiob,
|
||||||
.sda_pin = 7,
|
.sda_pin = PB7,
|
||||||
.scl_pin = 6,
|
.scl_pin = PB6,
|
||||||
.clk_id = RCC_I2C1,
|
.clk_id = RCC_I2C1,
|
||||||
.ev_nvic_line = NVIC_I2C1_EV,
|
.ev_nvic_line = NVIC_I2C1_EV,
|
||||||
.er_nvic_line = NVIC_I2C1_ER,
|
.er_nvic_line = NVIC_I2C1_ER,
|
||||||
|
@ -54,9 +54,9 @@ i2c_dev* const I2C1 = &i2c_dev1;
|
||||||
|
|
||||||
static i2c_dev i2c_dev2 = {
|
static i2c_dev i2c_dev2 = {
|
||||||
.regs = I2C2_BASE,
|
.regs = I2C2_BASE,
|
||||||
.gpio_port = &gpiob,
|
//.gpio_port = &gpiob,
|
||||||
.sda_pin = 11,
|
.sda_pin = PB11,
|
||||||
.scl_pin = 10,
|
.scl_pin = PB10,
|
||||||
.clk_id = RCC_I2C2,
|
.clk_id = RCC_I2C2,
|
||||||
.ev_nvic_line = NVIC_I2C2_EV,
|
.ev_nvic_line = NVIC_I2C2_EV,
|
||||||
.er_nvic_line = NVIC_I2C2_ER,
|
.er_nvic_line = NVIC_I2C2_ER,
|
||||||
|
@ -336,38 +336,38 @@ void __irq_i2c2_er(void) {
|
||||||
*/
|
*/
|
||||||
void i2c_bus_reset(const i2c_dev *dev) {
|
void i2c_bus_reset(const i2c_dev *dev) {
|
||||||
/* Release both lines */
|
/* Release both lines */
|
||||||
gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
|
gpio_set_pin(dev->scl_pin);
|
||||||
gpio_write_bit(dev->gpio_port, dev->sda_pin, 1);
|
gpio_set_pin(dev->sda_pin);
|
||||||
gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_OUTPUT_OD);
|
gpio_set_mode(dev->scl_pin, GPIO_OUTPUT_OD);
|
||||||
gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_OUTPUT_OD);
|
gpio_set_mode(dev->sda_pin, GPIO_OUTPUT_OD);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the bus is free by clocking it until any slaves release the
|
* Make sure the bus is free by clocking it until any slaves release the
|
||||||
* bus.
|
* bus.
|
||||||
*/
|
*/
|
||||||
while (!gpio_read_bit(dev->gpio_port, dev->sda_pin)) {
|
while (!gpio_read_pin(dev->sda_pin)) {
|
||||||
/* Wait for any clock stretching to finish */
|
/* Wait for any clock stretching to finish */
|
||||||
while (!gpio_read_bit(dev->gpio_port, dev->scl_pin))
|
while (!gpio_read_pin(dev->scl_pin))
|
||||||
;
|
;
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
|
|
||||||
/* Pull low */
|
/* Pull low */
|
||||||
gpio_write_bit(dev->gpio_port, dev->scl_pin, 0);
|
gpio_clear_pin(dev->scl_pin);
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
|
|
||||||
/* Release high again */
|
/* Release high again */
|
||||||
gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
|
gpio_set_pin(dev->scl_pin);
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate start then stop condition */
|
/* Generate start then stop condition */
|
||||||
gpio_write_bit(dev->gpio_port, dev->sda_pin, 0);
|
gpio_clear_pin(dev->sda_pin);
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
gpio_write_bit(dev->gpio_port, dev->scl_pin, 0);
|
gpio_clear_pin(dev->scl_pin);
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
gpio_write_bit(dev->gpio_port, dev->scl_pin, 1);
|
gpio_set_pin(dev->scl_pin);
|
||||||
delay_us(10);
|
delay_us(10);
|
||||||
gpio_write_bit(dev->gpio_port, dev->sda_pin, 1);
|
gpio_set_pin(dev->sda_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -413,8 +413,8 @@ void i2c_master_enable(i2c_dev *dev, uint32 flags) {
|
||||||
|
|
||||||
/* Turn on clock and set GPIO modes */
|
/* Turn on clock and set GPIO modes */
|
||||||
i2c_init(dev);
|
i2c_init(dev);
|
||||||
gpio_set_mode(dev->gpio_port, dev->sda_pin, GPIO_AF_OUTPUT_OD);
|
gpio_set_mode(dev->sda_pin, GPIO_AF_OUTPUT_OD);
|
||||||
gpio_set_mode(dev->gpio_port, dev->scl_pin, GPIO_AF_OUTPUT_OD);
|
gpio_set_mode(dev->scl_pin, GPIO_AF_OUTPUT_OD);
|
||||||
|
|
||||||
/* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */
|
/* I2C1 and I2C2 are fed from APB1, clocked at 36MHz */
|
||||||
i2c_set_input_clk(dev, I2C_CLK);
|
i2c_set_input_clk(dev, I2C_CLK);
|
||||||
|
|
|
@ -78,7 +78,7 @@ typedef struct i2c_msg {
|
||||||
*/
|
*/
|
||||||
typedef struct i2c_dev {
|
typedef struct i2c_dev {
|
||||||
i2c_reg_map *regs; /**< Register map */
|
i2c_reg_map *regs; /**< Register map */
|
||||||
gpio_dev *gpio_port; /**< SDA, SCL pins' GPIO port */
|
//gpio_dev *gpio_port; /**< SDA, SCL pins' GPIO port */
|
||||||
uint8 sda_pin; /**< SDA bit on gpio_port */
|
uint8 sda_pin; /**< SDA bit on gpio_port */
|
||||||
uint8 scl_pin; /**< SCL bit on gpio_port */
|
uint8 scl_pin; /**< SCL bit on gpio_port */
|
||||||
rcc_clk_id clk_id; /**< RCC clock information */
|
rcc_clk_id clk_id; /**< RCC clock information */
|
||||||
|
|
|
@ -32,29 +32,31 @@
|
||||||
#ifndef _LIBMAPLE_H_
|
#ifndef _LIBMAPLE_H_
|
||||||
#define _LIBMAPLE_H_
|
#define _LIBMAPLE_H_
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
#include "stm32.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "delay.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Where to put usercode, based on space reserved for bootloader.
|
* Where to put usercode, based on space reserved for bootloader.
|
||||||
*
|
*
|
||||||
* FIXME this has no business being here
|
* FIXME this has no business being here
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
#if defined(MCU_STM32F103VE) || defined(MCU_STM32F205VE) || defined(MCU_STM32F406VG)
|
#if defined(MCU_STM32F103VE) || defined(MCU_STM32F205VE) || defined(MCU_STM32F406VG)
|
||||||
/* e.g., Aeroquad32 */
|
// e.g., Aeroquad32
|
||||||
#define USER_ADDR_ROM 0x08010000 /* ala42 */
|
#define USER_ADDR_ROM 0x08010000 // ala42
|
||||||
#define USER_ADDR_RAM 0x20000C00
|
#define USER_ADDR_RAM 0x20000C00
|
||||||
#define STACK_TOP 0x20000800
|
#define STACK_TOP 0x20000800
|
||||||
#elif defined(BOARD_freeflight)
|
#elif defined(BOARD_freeflight)
|
||||||
|
*/
|
||||||
#define USER_ADDR_ROM 0x08000000
|
#define USER_ADDR_ROM 0x08000000
|
||||||
#define USER_ADDR_RAM 0x20000000
|
#define USER_ADDR_RAM 0x20000C00
|
||||||
#define STACK_TOP 0x20000800
|
#define STACK_TOP 0x20000800
|
||||||
|
/*
|
||||||
#else
|
#else
|
||||||
#define USER_ADDR_ROM 0x08005000
|
#define USER_ADDR_ROM 0x08005000
|
||||||
#define USER_ADDR_RAM 0x20000C00
|
#define USER_ADDR_RAM 0x20000C00
|
||||||
#define STACK_TOP 0x20000800
|
#define STACK_TOP 0x20000800
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#ifndef _LIBMAPLE_TYPES_H_
|
#ifndef _LIBMAPLE_TYPES_H_
|
||||||
#define _LIBMAPLE_TYPES_H_
|
#define _LIBMAPLE_TYPES_H_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
typedef unsigned char uint8;
|
typedef unsigned char uint8;
|
||||||
typedef unsigned short uint16;
|
typedef unsigned short uint16;
|
||||||
typedef unsigned int uint32;
|
typedef unsigned int uint32;
|
||||||
|
@ -46,12 +48,15 @@ typedef long long int64;
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
|
|
||||||
#define __io volatile
|
#define __io volatile
|
||||||
#define __attr_flash __attribute__((section (".USER_FLASH")))
|
#define __IO volatile
|
||||||
|
#ifndef __attr_flash
|
||||||
#define __always_inline inline __attribute__((always_inline))
|
#define __attr_flash __attribute__((section (".USER_FLASH")))
|
||||||
|
#endif
|
||||||
|
#ifndef __always_inline
|
||||||
|
#define __always_inline inline __attribute__((always_inline))
|
||||||
|
#endif
|
||||||
#ifndef NULL
|
#ifndef NULL
|
||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,8 +29,5 @@
|
||||||
* @brief reset and clock control definitions and prototypes
|
* @brief reset and clock control definitions and prototypes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef STM32F2
|
|
||||||
#include "rccF2.h"
|
#include "rccF4.h"
|
||||||
#else
|
|
||||||
#include "rccF1.h"
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,233 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef STM32F1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file rcc.c
|
|
||||||
* @brief Implements pretty much only the basic clock setup on the
|
|
||||||
* stm32, clock enable/disable and peripheral reset commands.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libmaple.h"
|
|
||||||
#include "flash.h"
|
|
||||||
#include "rcc.h"
|
|
||||||
#include "bitband.h"
|
|
||||||
|
|
||||||
#define APB1 RCC_APB1
|
|
||||||
#define APB2 RCC_APB2
|
|
||||||
#define AHB RCC_AHB
|
|
||||||
|
|
||||||
struct rcc_dev_info {
|
|
||||||
const rcc_clk_domain clk_domain;
|
|
||||||
const uint8 line_num;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Device descriptor table, maps rcc_clk_id onto bus and enable/reset
|
|
||||||
* register bit numbers. */
|
|
||||||
static 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},
|
|
||||||
#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
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the clock control system. Initializes the system
|
|
||||||
* clock source to use the PLL driven by an external oscillator
|
|
||||||
* @param sysclk_src system clock source, must be PLL
|
|
||||||
* @param pll_src pll clock source, must be HSE
|
|
||||||
* @param pll_mul pll multiplier
|
|
||||||
*/
|
|
||||||
void rcc_clk_init(rcc_sysclk_src sysclk_src,
|
|
||||||
rcc_pllsrc pll_src,
|
|
||||||
rcc_pll_multiplier pll_mul) {
|
|
||||||
uint32 cfgr = 0;
|
|
||||||
uint32 cr;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* Turn on the HSE */
|
|
||||||
cr = RCC_BASE->CR;
|
|
||||||
cr |= RCC_CR_HSEON;
|
|
||||||
RCC_BASE->CR = cr;
|
|
||||||
while (!(RCC_BASE->CR & RCC_CR_HSERDY))
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Now the PLL */
|
|
||||||
cr |= RCC_CR_PLLON;
|
|
||||||
RCC_BASE->CR = cr;
|
|
||||||
while (!(RCC_BASE->CR & RCC_CR_PLLRDY))
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Finally, let's switch over to the PLL */
|
|
||||||
cfgr &= ~RCC_CFGR_SW;
|
|
||||||
cfgr |= RCC_CFGR_SW_PLL;
|
|
||||||
RCC_BASE->CFGR = cfgr;
|
|
||||||
while ((RCC_BASE->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Turn on the clock line on a peripheral
|
|
||||||
* @param id Clock ID of the peripheral to turn on.
|
|
||||||
*/
|
|
||||||
void rcc_clk_enable(rcc_clk_id id) {
|
|
||||||
static const __io uint32* enable_regs[] = {
|
|
||||||
[APB1] = &RCC_BASE->APB1ENR,
|
|
||||||
[APB2] = &RCC_BASE->APB2ENR,
|
|
||||||
[AHB] = &RCC_BASE->AHBENR,
|
|
||||||
};
|
|
||||||
|
|
||||||
rcc_clk_domain clk_domain = rcc_dev_clk(id);
|
|
||||||
__io uint32* enr = (__io uint32*)enable_regs[clk_domain];
|
|
||||||
uint8 lnum = rcc_dev_table[id].line_num;
|
|
||||||
|
|
||||||
bb_peri_set_bit(enr, lnum, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset a peripheral.
|
|
||||||
* @param id Clock ID of the peripheral to reset.
|
|
||||||
*/
|
|
||||||
void rcc_reset_dev(rcc_clk_id id) {
|
|
||||||
static const __io uint32* reset_regs[] = {
|
|
||||||
[APB1] = &RCC_BASE->APB1RSTR,
|
|
||||||
[APB2] = &RCC_BASE->APB2RSTR,
|
|
||||||
};
|
|
||||||
|
|
||||||
rcc_clk_domain clk_domain = rcc_dev_clk(id);
|
|
||||||
__io void* addr = (__io void*)reset_regs[clk_domain];
|
|
||||||
uint8 lnum = rcc_dev_table[id].line_num;
|
|
||||||
|
|
||||||
bb_peri_set_bit(addr, lnum, 1);
|
|
||||||
bb_peri_set_bit(addr, lnum, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 Get a peripheral's clock domain speed
|
|
||||||
* @param id Clock ID of the peripheral whose clock domain speed to return
|
|
||||||
* @return Clock speed for the given clock ID
|
|
||||||
*/
|
|
||||||
uint32 rcc_dev_clk_speed(rcc_clk_id id) {
|
|
||||||
static const uint32 rcc_dev_clk_speed_table[] = {
|
|
||||||
[RCC_AHB] = 72000000,
|
|
||||||
[RCC_APB1] = 36000000,
|
|
||||||
[RCC_APB2] = 72000000
|
|
||||||
};
|
|
||||||
return rcc_dev_clk_speed_table[rcc_dev_clk(id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a peripheral's timer clock domain speed
|
|
||||||
* @param id Clock ID of the peripheral whose clock domain speed to return
|
|
||||||
* @return Clock speed for the given clock ID
|
|
||||||
*/
|
|
||||||
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id) {
|
|
||||||
return rcc_dev_clk_speed(RCC_APB2); // 72 MHz for all counter
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the divider on a peripheral prescaler
|
|
||||||
* @param prescaler prescaler to set
|
|
||||||
* @param divider prescaler divider
|
|
||||||
*/
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 cfgr = RCC_BASE->CFGR;
|
|
||||||
cfgr &= ~masks[prescaler];
|
|
||||||
cfgr |= divider;
|
|
||||||
RCC_BASE->CFGR = cfgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,572 +0,0 @@
|
||||||
/******************************************************************************
|
|
||||||
* 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 rcc.h
|
|
||||||
* @brief reset and clock control definitions and prototypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
|
|
||||||
#ifndef _RCC_H_
|
|
||||||
#define _RCC_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** RCC register map type */
|
|
||||||
typedef struct rcc_reg_map {
|
|
||||||
__io uint32 CR; /**< Clock control register */
|
|
||||||
__io uint32 CFGR; /**< Clock configuration register */
|
|
||||||
__io uint32 CIR; /**< Clock interrupt register */
|
|
||||||
__io uint32 APB2RSTR; /**< APB2 peripheral reset register */
|
|
||||||
__io uint32 APB1RSTR; /**< APB1 peripheral reset register */
|
|
||||||
__io uint32 AHBENR; /**< AHB peripheral clock enable register */
|
|
||||||
__io uint32 APB2ENR; /**< APB2 peripheral clock enable register */
|
|
||||||
__io uint32 APB1ENR; /**< APB1 peripheral clock enable register */
|
|
||||||
__io uint32 BDCR; /**< Backup domain control register */
|
|
||||||
__io uint32 CSR; /**< Control/status register */
|
|
||||||
} rcc_reg_map;
|
|
||||||
|
|
||||||
/** RCC register map base pointer */
|
|
||||||
#define RCC_BASE ((struct rcc_reg_map*)0x40021000)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register bit definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Clock control register */
|
|
||||||
|
|
||||||
#define RCC_CR_PLLRDY_BIT 25
|
|
||||||
#define RCC_CR_PLLON_BIT 24
|
|
||||||
#define RCC_CR_CSSON_BIT 19
|
|
||||||
#define RCC_CR_HSEBYP_BIT 18
|
|
||||||
#define RCC_CR_HSERDY_BIT 17
|
|
||||||
#define RCC_CR_HSEON_BIT 16
|
|
||||||
#define RCC_CR_HSIRDY_BIT 1
|
|
||||||
#define RCC_CR_HSION_BIT 0
|
|
||||||
|
|
||||||
#define RCC_CR_PLLRDY BIT(RCC_CR_PLLRDY_BIT)
|
|
||||||
#define RCC_CR_PLLON BIT(RCC_CR_PLLON_BIT)
|
|
||||||
#define RCC_CR_CSSON BIT(RCC_CR_CSSON_BIT)
|
|
||||||
#define RCC_CR_HSEBYP BIT(RCC_CR_HSEBYP_BIT)
|
|
||||||
#define RCC_CR_HSERDY BIT(RCC_CR_HSERDY_BIT)
|
|
||||||
#define RCC_CR_HSEON BIT(RCC_CR_HSEON_BIT)
|
|
||||||
#define RCC_CR_HSICAL (0xFF << 8)
|
|
||||||
#define RCC_CR_HSITRIM (0x1F << 3)
|
|
||||||
#define RCC_CR_HSIRDY BIT(RCC_CR_HSIRDY_BIT)
|
|
||||||
#define RCC_CR_HSION BIT(RCC_CR_HSION_BIT)
|
|
||||||
|
|
||||||
/* Clock configuration register */
|
|
||||||
|
|
||||||
#define RCC_CFGR_USBPRE_BIT 22
|
|
||||||
#define RCC_CFGR_PLLXTPRE_BIT 17
|
|
||||||
#define RCC_CFGR_PLLSRC_BIT 16
|
|
||||||
|
|
||||||
#define RCC_CFGR_MCO (0x3 << 24)
|
|
||||||
#define RCC_CFGR_USBPRE BIT(RCC_CFGR_USBPRE_BIT)
|
|
||||||
#define RCC_CFGR_PLLMUL (0xF << 18)
|
|
||||||
#define RCC_CFGR_PLLXTPRE BIT(RCC_CFGR_PLLXTPRE_BIT)
|
|
||||||
#define RCC_CFGR_PLLSRC BIT(RCC_CFGR_PLLSRC_BIT)
|
|
||||||
#define RCC_CFGR_ADCPRE (0x3 << 14)
|
|
||||||
#define RCC_CFGR_PPRE2 (0x7 << 11)
|
|
||||||
#define RCC_CFGR_PPRE1 (0x7 << 8)
|
|
||||||
#define RCC_CFGR_HPRE (0xF << 4)
|
|
||||||
#define RCC_CFGR_SWS (0x3 << 2)
|
|
||||||
#define RCC_CFGR_SWS_PLL (0x2 << 2)
|
|
||||||
#define RCC_CFGR_SWS_HSE (0x1 << 2)
|
|
||||||
#define RCC_CFGR_SW 0x3
|
|
||||||
#define RCC_CFGR_SW_PLL 0x2
|
|
||||||
#define RCC_CFGR_SW_HSE 0x1
|
|
||||||
|
|
||||||
/* Clock interrupt register */
|
|
||||||
|
|
||||||
#define RCC_CIR_CSSC_BIT 23
|
|
||||||
#define RCC_CIR_PLLRDYC_BIT 20
|
|
||||||
#define RCC_CIR_HSERDYC_BIT 19
|
|
||||||
#define RCC_CIR_HSIRDYC_BIT 18
|
|
||||||
#define RCC_CIR_LSERDYC_BIT 17
|
|
||||||
#define RCC_CIR_LSIRDYC_BIT 16
|
|
||||||
#define RCC_CIR_PLLRDYIE_BIT 12
|
|
||||||
#define RCC_CIR_HSERDYIE_BIT 11
|
|
||||||
#define RCC_CIR_HSIRDYIE_BIT 10
|
|
||||||
#define RCC_CIR_LSERDYIE_BIT 9
|
|
||||||
#define RCC_CIR_LSIRDYIE_BIT 8
|
|
||||||
#define RCC_CIR_CSSF_BIT 7
|
|
||||||
#define RCC_CIR_PLLRDYF_BIT 4
|
|
||||||
#define RCC_CIR_HSERDYF_BIT 3
|
|
||||||
#define RCC_CIR_HSIRDYF_BIT 2
|
|
||||||
#define RCC_CIR_LSERDYF_BIT 1
|
|
||||||
#define RCC_CIR_LSIRDYF_BIT 0
|
|
||||||
|
|
||||||
#define RCC_CIR_CSSC BIT(RCC_CIR_CSSC_BIT)
|
|
||||||
#define RCC_CIR_PLLRDYC BIT(RCC_CIR_PLLRDYC_BIT)
|
|
||||||
#define RCC_CIR_HSERDYC BIT(RCC_CIR_HSERDYC_BIT)
|
|
||||||
#define RCC_CIR_HSIRDYC BIT(RCC_CIR_HSIRDYC_BIT)
|
|
||||||
#define RCC_CIR_LSERDYC BIT(RCC_CIR_LSERDYC_BIT)
|
|
||||||
#define RCC_CIR_LSIRDYC BIT(RCC_CIR_LSIRDYC_BIT)
|
|
||||||
#define RCC_CIR_PLLRDYIE BIT(RCC_CIR_PLLRDYIE_BIT)
|
|
||||||
#define RCC_CIR_HSERDYIE BIT(RCC_CIR_HSERDYIE_BIT)
|
|
||||||
#define RCC_CIR_HSIRDYIE BIT(RCC_CIR_HSIRDYIE_BIT)
|
|
||||||
#define RCC_CIR_LSERDYIE BIT(RCC_CIR_LSERDYIE_BIT)
|
|
||||||
#define RCC_CIR_LSIRDYIE BIT(RCC_CIR_LSIRDYIE_BIT)
|
|
||||||
#define RCC_CIR_CSSF BIT(RCC_CIR_CSSF_BIT)
|
|
||||||
#define RCC_CIR_PLLRDYF BIT(RCC_CIR_PLLRDYF_BIT)
|
|
||||||
#define RCC_CIR_HSERDYF BIT(RCC_CIR_HSERDYF_BIT)
|
|
||||||
#define RCC_CIR_HSIRDYF BIT(RCC_CIR_HSIRDYF_BIT)
|
|
||||||
#define RCC_CIR_LSERDYF BIT(RCC_CIR_LSERDYF_BIT)
|
|
||||||
#define RCC_CIR_LSIRDYF BIT(RCC_CIR_LSIRDYF_BIT)
|
|
||||||
|
|
||||||
/* APB2 peripheral reset register */
|
|
||||||
|
|
||||||
#define RCC_APB2RSTR_TIM11RST_BIT 21
|
|
||||||
#define RCC_APB2RSTR_TIM10RST_BIT 20
|
|
||||||
#define RCC_APB2RSTR_TIM9RST_BIT 19
|
|
||||||
#define RCC_APB2RSTR_ADC3RST_BIT 15
|
|
||||||
#define RCC_APB2RSTR_USART1RST_BIT 14
|
|
||||||
#define RCC_APB2RSTR_TIM8RST_BIT 13
|
|
||||||
#define RCC_APB2RSTR_SPI1RST_BIT 12
|
|
||||||
#define RCC_APB2RSTR_TIM1RST_BIT 11
|
|
||||||
#define RCC_APB2RSTR_ADC2RST_BIT 10
|
|
||||||
#define RCC_APB2RSTR_ADC1RST_BIT 9
|
|
||||||
#define RCC_APB2RSTR_IOPGRST_BIT 8
|
|
||||||
#define RCC_APB2RSTR_IOPFRST_BIT 7
|
|
||||||
#define RCC_APB2RSTR_IOPERST_BIT 6
|
|
||||||
#define RCC_APB2RSTR_IOPDRST_BIT 5
|
|
||||||
#define RCC_APB2RSTR_IOPCRST_BIT 4
|
|
||||||
#define RCC_APB2RSTR_IOPBRST_BIT 3
|
|
||||||
#define RCC_APB2RSTR_IOPARST_BIT 2
|
|
||||||
#define RCC_APB2RSTR_AFIORST_BIT 0
|
|
||||||
|
|
||||||
#define RCC_APB2RSTR_TIM11RST BIT(RCC_APB2RSTR_TIM11RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_TIM10RST BIT(RCC_APB2RSTR_TIM10RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_TIM9RST BIT(RCC_APB2RSTR_TIM9RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_ADC3RST BIT(RCC_APB2RSTR_ADC3RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_USART1RST BIT(RCC_APB2RSTR_USART1RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_TIM8RST BIT(RCC_APB2RSTR_TIM8RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_SPI1RST BIT(RCC_APB2RSTR_SPI1RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_TIM1RST BIT(RCC_APB2RSTR_TIM1RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_ADC2RST BIT(RCC_APB2RSTR_ADC2RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_ADC1RST BIT(RCC_APB2RSTR_ADC1RST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPGRST BIT(RCC_APB2RSTR_IOPGRST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPFRST BIT(RCC_APB2RSTR_IOPFRST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPERST BIT(RCC_APB2RSTR_IOPERST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPDRST BIT(RCC_APB2RSTR_IOPDRST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPCRST BIT(RCC_APB2RSTR_IOPCRST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPBRST BIT(RCC_APB2RSTR_IOPBRST_BIT)
|
|
||||||
#define RCC_APB2RSTR_IOPARST BIT(RCC_APB2RSTR_IOPARST_BIT)
|
|
||||||
#define RCC_APB2RSTR_AFIORST BIT(RCC_APB2RSTR_AFIORST_BIT)
|
|
||||||
|
|
||||||
/* APB1 peripheral reset register */
|
|
||||||
|
|
||||||
#define RCC_APB1RSTR_DACRST_BIT 29
|
|
||||||
#define RCC_APB1RSTR_PWRRST_BIT 28
|
|
||||||
#define RCC_APB1RSTR_BKPRST_BIT 27
|
|
||||||
#define RCC_APB1RSTR_CANRST_BIT 25
|
|
||||||
#define RCC_APB1RSTR_USBRST_BIT 23
|
|
||||||
#define RCC_APB1RSTR_I2C2RST_BIT 22
|
|
||||||
#define RCC_APB1RSTR_I2C1RST_BIT 21
|
|
||||||
#define RCC_APB1RSTR_UART5RST_BIT 20
|
|
||||||
#define RCC_APB1RSTR_UART4RST_BIT 19
|
|
||||||
#define RCC_APB1RSTR_USART3RST_BIT 18
|
|
||||||
#define RCC_APB1RSTR_USART2RST_BIT 17
|
|
||||||
#define RCC_APB1RSTR_SPI3RST_BIT 15
|
|
||||||
#define RCC_APB1RSTR_SPI2RST_BIT 14
|
|
||||||
#define RCC_APB1RSTR_WWDRST_BIT 11
|
|
||||||
#define RCC_APB1RSTR_TIM14RST_BIT 8
|
|
||||||
#define RCC_APB1RSTR_TIM13RST_BIT 7
|
|
||||||
#define RCC_APB1RSTR_TIM12RST_BIT 6
|
|
||||||
#define RCC_APB1RSTR_TIM7RST_BIT 5
|
|
||||||
#define RCC_APB1RSTR_TIM6RST_BIT 4
|
|
||||||
#define RCC_APB1RSTR_TIM5RST_BIT 3
|
|
||||||
#define RCC_APB1RSTR_TIM4RST_BIT 2
|
|
||||||
#define RCC_APB1RSTR_TIM3RST_BIT 1
|
|
||||||
#define RCC_APB1RSTR_TIM2RST_BIT 0
|
|
||||||
|
|
||||||
#define RCC_APB1RSTR_DACRST BIT(RCC_APB1RSTR_DACRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_PWRRST BIT(RCC_APB1RSTR_PWRRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_BKPRST BIT(RCC_APB1RSTR_BKPRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_CANRST BIT(RCC_APB1RSTR_CANRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_USBRST BIT(RCC_APB1RSTR_USBRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_I2C2RST BIT(RCC_APB1RSTR_I2C2RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_I2C1RST BIT(RCC_APB1RSTR_I2C1RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_UART5RST BIT(RCC_APB1RSTR_UART5RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_UART4RST BIT(RCC_APB1RSTR_UART4RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_USART3RST BIT(RCC_APB1RSTR_USART3RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_USART2RST BIT(RCC_APB1RSTR_USART2RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_SPI3RST BIT(RCC_APB1RSTR_SPI3RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_SPI2RST BIT(RCC_APB1RSTR_SPI2RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_WWDRST BIT(RCC_APB1RSTR_WWDRST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM14RST BIT(RCC_APB1RSTR_TIM14RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM13RST BIT(RCC_APB1RSTR_TIM13RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM12RST BIT(RCC_APB1RSTR_TIM12RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM7RST BIT(RCC_APB1RSTR_TIM7RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM6RST BIT(RCC_APB1RSTR_TIM6RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM5RST BIT(RCC_APB1RSTR_TIM5RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM4RST BIT(RCC_APB1RSTR_TIM4RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM3RST BIT(RCC_APB1RSTR_TIM3RST_BIT)
|
|
||||||
#define RCC_APB1RSTR_TIM2RST BIT(RCC_APB1RSTR_TIM2RST_BIT)
|
|
||||||
|
|
||||||
/* AHB peripheral clock enable register */
|
|
||||||
|
|
||||||
#define RCC_AHBENR_SDIOEN_BIT 10
|
|
||||||
#define RCC_AHBENR_FSMCEN_BIT 8
|
|
||||||
#define RCC_AHBENR_CRCEN_BIT 7
|
|
||||||
#define RCC_AHBENR_FLITFEN_BIT 4
|
|
||||||
#define RCC_AHBENR_SRAMEN_BIT 2
|
|
||||||
#define RCC_AHBENR_DMA2EN_BIT 1
|
|
||||||
#define RCC_AHBENR_DMA1EN_BIT 0
|
|
||||||
|
|
||||||
#define RCC_AHBENR_SDIOEN BIT(RCC_AHBENR_SDIOEN_BIT)
|
|
||||||
#define RCC_AHBENR_FSMCEN BIT(RCC_AHBENR_FSMCEN_BIT)
|
|
||||||
#define RCC_AHBENR_CRCEN BIT(RCC_AHBENR_CRCEN_BIT)
|
|
||||||
#define RCC_AHBENR_FLITFEN BIT(RCC_AHBENR_FLITFEN_BIT)
|
|
||||||
#define RCC_AHBENR_SRAMEN BIT(RCC_AHBENR_SRAMEN_BIT)
|
|
||||||
#define RCC_AHBENR_DMA2EN BIT(RCC_AHBENR_DMA2EN_BIT)
|
|
||||||
#define RCC_AHBENR_DMA1EN BIT(RCC_AHBENR_DMA1EN_BIT)
|
|
||||||
|
|
||||||
/* APB2 peripheral clock enable register */
|
|
||||||
|
|
||||||
#define RCC_APB2ENR_TIM11EN_BIT 21
|
|
||||||
#define RCC_APB2ENR_TIM10EN_BIT 20
|
|
||||||
#define RCC_APB2ENR_TIM9EN_BIT 19
|
|
||||||
#define RCC_APB2ENR_ADC3EN_BIT 15
|
|
||||||
#define RCC_APB2ENR_USART1EN_BIT 14
|
|
||||||
#define RCC_APB2ENR_TIM8EN_BIT 13
|
|
||||||
#define RCC_APB2ENR_SPI1EN_BIT 12
|
|
||||||
#define RCC_APB2ENR_TIM1EN_BIT 11
|
|
||||||
#define RCC_APB2ENR_ADC2EN_BIT 10
|
|
||||||
#define RCC_APB2ENR_ADC1EN_BIT 9
|
|
||||||
#define RCC_APB2ENR_IOPGEN_BIT 8
|
|
||||||
#define RCC_APB2ENR_IOPFEN_BIT 7
|
|
||||||
#define RCC_APB2ENR_IOPEEN_BIT 6
|
|
||||||
#define RCC_APB2ENR_IOPDEN_BIT 5
|
|
||||||
#define RCC_APB2ENR_IOPCEN_BIT 4
|
|
||||||
#define RCC_APB2ENR_IOPBEN_BIT 3
|
|
||||||
#define RCC_APB2ENR_IOPAEN_BIT 2
|
|
||||||
#define RCC_APB2ENR_AFIOEN_BIT 0
|
|
||||||
|
|
||||||
#define RCC_APB2ENR_TIM11EN BIT(RCC_APB2ENR_TIM11EN_BIT)
|
|
||||||
#define RCC_APB2ENR_TIM10EN BIT(RCC_APB2ENR_TIM10EN_BIT)
|
|
||||||
#define RCC_APB2ENR_TIM9EN BIT(RCC_APB2ENR_TIM9EN_BIT)
|
|
||||||
#define RCC_APB2ENR_ADC3EN BIT(RCC_APB2ENR_ADC3EN_BIT)
|
|
||||||
#define RCC_APB2ENR_USART1EN BIT(RCC_APB2ENR_USART1EN_BIT)
|
|
||||||
#define RCC_APB2ENR_TIM8EN BIT(RCC_APB2ENR_TIM8EN_BIT)
|
|
||||||
#define RCC_APB2ENR_SPI1EN BIT(RCC_APB2ENR_SPI1EN_BIT)
|
|
||||||
#define RCC_APB2ENR_TIM1EN BIT(RCC_APB2ENR_TIM1EN_BIT)
|
|
||||||
#define RCC_APB2ENR_ADC2EN BIT(RCC_APB2ENR_ADC2EN_BIT)
|
|
||||||
#define RCC_APB2ENR_ADC1EN BIT(RCC_APB2ENR_ADC1EN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPGEN BIT(RCC_APB2ENR_IOPGEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPFEN BIT(RCC_APB2ENR_IOPFEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPEEN BIT(RCC_APB2ENR_IOPEEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPDEN BIT(RCC_APB2ENR_IOPDEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPCEN BIT(RCC_APB2ENR_IOPCEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPBEN BIT(RCC_APB2ENR_IOPBEN_BIT)
|
|
||||||
#define RCC_APB2ENR_IOPAEN BIT(RCC_APB2ENR_IOPAEN_BIT)
|
|
||||||
#define RCC_APB2ENR_AFIOEN BIT(RCC_APB2ENR_AFIOEN_BIT)
|
|
||||||
|
|
||||||
/* APB1 peripheral clock enable register */
|
|
||||||
|
|
||||||
#define RCC_APB1ENR_DACEN_BIT 29
|
|
||||||
#define RCC_APB1ENR_PWREN_BIT 28
|
|
||||||
#define RCC_APB1ENR_BKPEN_BIT 27
|
|
||||||
#define RCC_APB1ENR_CANEN_BIT 25
|
|
||||||
#define RCC_APB1ENR_USBEN_BIT 23
|
|
||||||
#define RCC_APB1ENR_I2C2EN_BIT 22
|
|
||||||
#define RCC_APB1ENR_I2C1EN_BIT 21
|
|
||||||
#define RCC_APB1ENR_UART5EN_BIT 20
|
|
||||||
#define RCC_APB1ENR_UART4EN_BIT 19
|
|
||||||
#define RCC_APB1ENR_USART3EN_BIT 18
|
|
||||||
#define RCC_APB1ENR_USART2EN_BIT 17
|
|
||||||
#define RCC_APB1ENR_SPI3EN_BIT 15
|
|
||||||
#define RCC_APB1ENR_SPI2EN_BIT 14
|
|
||||||
#define RCC_APB1ENR_WWDEN_BIT 11
|
|
||||||
#define RCC_APB1ENR_TIM14EN_BIT 8
|
|
||||||
#define RCC_APB1ENR_TIM13EN_BIT 7
|
|
||||||
#define RCC_APB1ENR_TIM12EN_BIT 6
|
|
||||||
#define RCC_APB1ENR_TIM7EN_BIT 5
|
|
||||||
#define RCC_APB1ENR_TIM6EN_BIT 4
|
|
||||||
#define RCC_APB1ENR_TIM5EN_BIT 3
|
|
||||||
#define RCC_APB1ENR_TIM4EN_BIT 2
|
|
||||||
#define RCC_APB1ENR_TIM3EN_BIT 1
|
|
||||||
#define RCC_APB1ENR_TIM2EN_BIT 0
|
|
||||||
|
|
||||||
#define RCC_APB1ENR_DACEN BIT(RCC_APB1ENR_DACEN_BIT)
|
|
||||||
#define RCC_APB1ENR_PWREN BIT(RCC_APB1ENR_PWREN_BIT)
|
|
||||||
#define RCC_APB1ENR_BKPEN BIT(RCC_APB1ENR_BKPEN_BIT)
|
|
||||||
#define RCC_APB1ENR_CANEN BIT(RCC_APB1ENR_CANEN_BIT)
|
|
||||||
#define RCC_APB1ENR_USBEN BIT(RCC_APB1ENR_USBEN_BIT)
|
|
||||||
#define RCC_APB1ENR_I2C2EN BIT(RCC_APB1ENR_I2C2EN_BIT)
|
|
||||||
#define RCC_APB1ENR_I2C1EN BIT(RCC_APB1ENR_I2C1EN_BIT)
|
|
||||||
#define RCC_APB1ENR_UART5EN BIT(RCC_APB1ENR_UART5EN_BIT)
|
|
||||||
#define RCC_APB1ENR_UART4EN BIT(RCC_APB1ENR_UART4EN_BIT)
|
|
||||||
#define RCC_APB1ENR_USART3EN BIT(RCC_APB1ENR_USART3EN_BIT)
|
|
||||||
#define RCC_APB1ENR_USART2EN BIT(RCC_APB1ENR_USART2EN_BIT)
|
|
||||||
#define RCC_APB1ENR_SPI3EN BIT(RCC_APB1ENR_SPI3EN_BIT)
|
|
||||||
#define RCC_APB1ENR_SPI2EN BIT(RCC_APB1ENR_SPI2EN_BIT)
|
|
||||||
#define RCC_APB1ENR_WWDEN BIT(RCC_APB1ENR_WWDEN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM14EN BIT(RCC_APB1ENR_TIM14EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM13EN BIT(RCC_APB1ENR_TIM13EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM12EN BIT(RCC_APB1ENR_TIM12EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM7EN BIT(RCC_APB1ENR_TIM7EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM6EN BIT(RCC_APB1ENR_TIM6EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM5EN BIT(RCC_APB1ENR_TIM5EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM4EN BIT(RCC_APB1ENR_TIM4EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM3EN BIT(RCC_APB1ENR_TIM3EN_BIT)
|
|
||||||
#define RCC_APB1ENR_TIM2EN BIT(RCC_APB1ENR_TIM2EN_BIT)
|
|
||||||
|
|
||||||
/* Backup domain control register */
|
|
||||||
|
|
||||||
#define RCC_BDCR_BDRST_BIT 16
|
|
||||||
#define RCC_BDCR_RTCEN_BIT 15
|
|
||||||
#define RCC_BDCR_LSEBYP_BIT 2
|
|
||||||
#define RCC_BDCR_LSERDY_BIT 1
|
|
||||||
#define RCC_BDCR_LSEON_BIT 0
|
|
||||||
|
|
||||||
#define RCC_BDCR_BDRST BIT(RCC_BDCR_BDRST_BIT)
|
|
||||||
#define RCC_BDCR_RTCEN BIT(RCC_BDCR_RTC_BIT)
|
|
||||||
#define RCC_BDCR_RTCSEL (0x3 << 8)
|
|
||||||
#define RCC_BDCR_RTCSEL_NONE (0x0 << 8)
|
|
||||||
#define RCC_BDCR_RTCSEL_LSE (0x1 << 8)
|
|
||||||
#define RCC_BDCR_RTCSEL_HSE (0x3 << 8)
|
|
||||||
#define RCC_BDCR_LSEBYP BIT(RCC_BDCR_LSEBYP_BIT)
|
|
||||||
#define RCC_BDCR_LSERDY BIT(RCC_BDCR_LSERDY_BIT)
|
|
||||||
#define RCC_BDCR_LSEON BIT(RCC_BDCR_LSEON_BIT)
|
|
||||||
|
|
||||||
/* Control/status register */
|
|
||||||
|
|
||||||
#define RCC_CSR_LPWRRSTF_BIT 31
|
|
||||||
#define RCC_CSR_WWDGRSTF_BIT 30
|
|
||||||
#define RCC_CSR_IWDGRSTF_BIT 29
|
|
||||||
#define RCC_CSR_SFTRSTF_BIT 28
|
|
||||||
#define RCC_CSR_PORRSTF_BIT 27
|
|
||||||
#define RCC_CSR_PINRSTF_BIT 26
|
|
||||||
#define RCC_CSR_RMVF_BIT 24
|
|
||||||
#define RCC_CSR_LSIRDY_BIT 1
|
|
||||||
#define RCC_CSR_LSION_BIT 0
|
|
||||||
|
|
||||||
#define RCC_CSR_LPWRRSTF BIT(RCC_CSR_LPWRRSTF_BIT)
|
|
||||||
#define RCC_CSR_WWDGRSTF BIT(RCC_CSR_WWDGRSTF_BIT)
|
|
||||||
#define RCC_CSR_IWDGRSTF BIT(RCC_CSR_IWDGRSTF_BIT)
|
|
||||||
#define RCC_CSR_SFTRSTF BIT(RCC_CSR_SFTRSTF_BIT)
|
|
||||||
#define RCC_CSR_PORRSTF BIT(RCC_CSR_PORRSTF_BIT)
|
|
||||||
#define RCC_CSR_PINRSTF BIT(RCC_CSR_PINRSTF_BIT)
|
|
||||||
#define RCC_CSR_RMVF BIT(RCC_CSR_RMVF_BIT)
|
|
||||||
#define RCC_CSR_LSIRDY BIT(RCC_CSR_LSIRDY_BIT)
|
|
||||||
#define RCC_CSR_LSION BIT(RCC_CSR_LSION_BIT)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SYSCLK sources
|
|
||||||
* @see rcc_clk_init()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_sysclk_src {
|
|
||||||
RCC_CLKSRC_HSI = 0x0,
|
|
||||||
RCC_CLKSRC_HSE = 0x1,
|
|
||||||
RCC_CLKSRC_PLL = 0x2,
|
|
||||||
} rcc_sysclk_src;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PLL entry clock source
|
|
||||||
* @see rcc_clk_init()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_pllsrc {
|
|
||||||
RCC_PLLSRC_HSE = (0x1 << 16),
|
|
||||||
RCC_PLLSRC_HSI_DIV_2 = (0x0 << 16)
|
|
||||||
} rcc_pllsrc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PLL multipliers
|
|
||||||
* @see rcc_clk_init()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_pll_multiplier {
|
|
||||||
RCC_PLLMUL_2 = (0x0 << 18),
|
|
||||||
RCC_PLLMUL_3 = (0x1 << 18),
|
|
||||||
RCC_PLLMUL_4 = (0x2 << 18),
|
|
||||||
RCC_PLLMUL_5 = (0x3 << 18),
|
|
||||||
RCC_PLLMUL_6 = (0x4 << 18),
|
|
||||||
RCC_PLLMUL_7 = (0x5 << 18),
|
|
||||||
RCC_PLLMUL_8 = (0x6 << 18),
|
|
||||||
RCC_PLLMUL_9 = (0x7 << 18),
|
|
||||||
RCC_PLLMUL_10 = (0x8 << 18),
|
|
||||||
RCC_PLLMUL_11 = (0x9 << 18),
|
|
||||||
RCC_PLLMUL_12 = (0xA << 18),
|
|
||||||
RCC_PLLMUL_13 = (0xB << 18),
|
|
||||||
RCC_PLLMUL_14 = (0xC << 18),
|
|
||||||
RCC_PLLMUL_15 = (0xD << 18),
|
|
||||||
RCC_PLLMUL_16 = (0xE << 18),
|
|
||||||
} rcc_pll_multiplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Identifies bus and clock line for a peripheral.
|
|
||||||
*
|
|
||||||
* Also generally useful as a unique identifier for that peripheral
|
|
||||||
* (or its corresponding device struct).
|
|
||||||
*/
|
|
||||||
typedef enum rcc_clk_id {
|
|
||||||
RCC_GPIOA,
|
|
||||||
RCC_GPIOB,
|
|
||||||
RCC_GPIOC,
|
|
||||||
RCC_GPIOD,
|
|
||||||
RCC_AFIO,
|
|
||||||
RCC_ADC1,
|
|
||||||
RCC_ADC2,
|
|
||||||
RCC_ADC3,
|
|
||||||
RCC_USART1,
|
|
||||||
RCC_USART2,
|
|
||||||
RCC_USART3,
|
|
||||||
RCC_TIMER1,
|
|
||||||
RCC_TIMER2,
|
|
||||||
RCC_TIMER3,
|
|
||||||
RCC_TIMER4,
|
|
||||||
RCC_SPI1,
|
|
||||||
RCC_SPI2,
|
|
||||||
RCC_DMA1,
|
|
||||||
RCC_PWR,
|
|
||||||
RCC_BKP,
|
|
||||||
RCC_I2C1,
|
|
||||||
RCC_I2C2,
|
|
||||||
RCC_CRC,
|
|
||||||
RCC_FLITF,
|
|
||||||
RCC_SRAM,
|
|
||||||
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
|
|
||||||
RCC_GPIOE,
|
|
||||||
RCC_GPIOF,
|
|
||||||
RCC_GPIOG,
|
|
||||||
RCC_UART4,
|
|
||||||
RCC_UART5,
|
|
||||||
RCC_TIMER5,
|
|
||||||
RCC_TIMER6,
|
|
||||||
RCC_TIMER7,
|
|
||||||
RCC_TIMER8,
|
|
||||||
RCC_FSMC,
|
|
||||||
RCC_DAC,
|
|
||||||
RCC_DMA2,
|
|
||||||
RCC_SDIO,
|
|
||||||
RCC_SPI3,
|
|
||||||
#endif
|
|
||||||
#ifdef STM32_XL_DENSITY
|
|
||||||
RCC_TIMER9,
|
|
||||||
RCC_TIMER10,
|
|
||||||
RCC_TIMER11,
|
|
||||||
RCC_TIMER12,
|
|
||||||
RCC_TIMER13,
|
|
||||||
RCC_TIMER14,
|
|
||||||
#endif
|
|
||||||
} rcc_clk_id;
|
|
||||||
|
|
||||||
void rcc_clk_init(rcc_sysclk_src sysclk_src,
|
|
||||||
rcc_pllsrc pll_src,
|
|
||||||
rcc_pll_multiplier pll_mul);
|
|
||||||
void rcc_clk_enable(rcc_clk_id device);
|
|
||||||
void rcc_reset_dev(rcc_clk_id device);
|
|
||||||
|
|
||||||
typedef enum rcc_clk_domain {
|
|
||||||
RCC_APB1,
|
|
||||||
RCC_APB2,
|
|
||||||
RCC_AHB
|
|
||||||
} rcc_clk_domain;
|
|
||||||
|
|
||||||
rcc_clk_domain rcc_dev_clk(rcc_clk_id device);
|
|
||||||
|
|
||||||
uint32 rcc_dev_clk_speed(rcc_clk_id id);
|
|
||||||
uint32 rcc_dev_timer_clk_speed(rcc_clk_id id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prescaler identifiers
|
|
||||||
* @see rcc_set_prescaler()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_prescaler {
|
|
||||||
RCC_PRESCALER_AHB,
|
|
||||||
RCC_PRESCALER_APB1,
|
|
||||||
RCC_PRESCALER_APB2,
|
|
||||||
RCC_PRESCALER_USB,
|
|
||||||
RCC_PRESCALER_ADC
|
|
||||||
} rcc_prescaler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ADC prescaler dividers
|
|
||||||
* @see rcc_set_prescaler()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_adc_divider {
|
|
||||||
RCC_ADCPRE_PCLK_DIV_2 = 0x0 << 14,
|
|
||||||
RCC_ADCPRE_PCLK_DIV_4 = 0x1 << 14,
|
|
||||||
RCC_ADCPRE_PCLK_DIV_6 = 0x2 << 14,
|
|
||||||
RCC_ADCPRE_PCLK_DIV_8 = 0x3 << 14,
|
|
||||||
} rcc_adc_divider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* APB1 prescaler dividers
|
|
||||||
* @see rcc_set_prescaler()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_apb1_divider {
|
|
||||||
RCC_APB1_HCLK_DIV_1 = 0x0 << 8,
|
|
||||||
RCC_APB1_HCLK_DIV_2 = 0x4 << 8,
|
|
||||||
RCC_APB1_HCLK_DIV_4 = 0x5 << 8,
|
|
||||||
RCC_APB1_HCLK_DIV_8 = 0x6 << 8,
|
|
||||||
RCC_APB1_HCLK_DIV_16 = 0x7 << 8,
|
|
||||||
} rcc_apb1_divider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* APB2 prescaler dividers
|
|
||||||
* @see rcc_set_prescaler()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_apb2_divider {
|
|
||||||
RCC_APB2_HCLK_DIV_1 = 0x0 << 11,
|
|
||||||
RCC_APB2_HCLK_DIV_2 = 0x4 << 11,
|
|
||||||
RCC_APB2_HCLK_DIV_4 = 0x5 << 11,
|
|
||||||
RCC_APB2_HCLK_DIV_8 = 0x6 << 11,
|
|
||||||
RCC_APB2_HCLK_DIV_16 = 0x7 << 11,
|
|
||||||
} rcc_apb2_divider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AHB prescaler dividers
|
|
||||||
* @see rcc_set_prescaler()
|
|
||||||
*/
|
|
||||||
typedef enum rcc_ahb_divider {
|
|
||||||
RCC_AHB_SYSCLK_DIV_1 = 0x0 << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_2 = 0x8 << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_4 = 0x9 << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_8 = 0xA << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_16 = 0xB << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_32 = 0xC << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_64 = 0xD << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_128 = 0xD << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_256 = 0xE << 4,
|
|
||||||
RCC_AHB_SYSCLK_DIV_512 = 0xF << 4,
|
|
||||||
} rcc_ahb_divider;
|
|
||||||
|
|
||||||
void rcc_set_prescaler(rcc_prescaler prescaler, uint32 divider);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -24,7 +24,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifdef STM32F2
|
#ifdef STM32F4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file rcc.c
|
* @file rcc.c
|
||||||
|
@ -166,7 +166,6 @@ typedef struct
|
||||||
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
|
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
|
||||||
#define RESET 0
|
#define RESET 0
|
||||||
|
|
||||||
typedef uint32 uint32_t;
|
|
||||||
|
|
||||||
void InitMCO1()
|
void InitMCO1()
|
||||||
{
|
{
|
||||||
|
@ -175,8 +174,8 @@ void InitMCO1()
|
||||||
RCC->CFGR &= RCC_CFGR_MCO1_RESET_MASK;
|
RCC->CFGR &= RCC_CFGR_MCO1_RESET_MASK;
|
||||||
RCC->CFGR |= RCC_CFGR_MCO1Source_HSE | RCC_CFGR_MCO1Div_1;
|
RCC->CFGR |= RCC_CFGR_MCO1Source_HSE | RCC_CFGR_MCO1Div_1;
|
||||||
// PA8 Output the Master Clock MCO1
|
// PA8 Output the Master Clock MCO1
|
||||||
gpio_set_af_mode(GPIOA, 8, 0);
|
gpio_set_af_mode(PA8, 0);
|
||||||
gpio_set_mode(GPIOA, 8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
gpio_set_mode(PA8, GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,11 @@ sp := $(sp).x
|
||||||
dirstack_$(sp) := $(d)
|
dirstack_$(sp) := $(d)
|
||||||
d := $(dir)
|
d := $(dir)
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)
|
BUILDDIRS += $(BUILD_PATH)/$(d)
|
||||||
ifneq ($(MCU_FAMILY), STM32F2)
|
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usb
|
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usb/usb_lib
|
|
||||||
LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usb -I$(LIBMAPLE_PATH)/usb/usb_lib
|
|
||||||
else
|
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Core/src
|
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Core/src
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Class/cdc/src
|
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_Device_Library/Class/cdc/src
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_OTG_Driver/src
|
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/STM32_USB_OTG_Driver/src
|
||||||
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/VCP
|
BUILDDIRS += $(BUILD_PATH)/$(d)/usbF4/VCP
|
||||||
LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usbF4
|
LIBMAPLE_INCLUDES := -I$(LIBMAPLE_PATH) -I$(LIBMAPLE_PATH)/usbF4
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# Local flags
|
# Local flags
|
||||||
|
@ -42,18 +36,6 @@ cSRCS_$(d) := adc.c \
|
||||||
usart.c \
|
usart.c \
|
||||||
util.c
|
util.c
|
||||||
|
|
||||||
ifneq ($(MCU_FAMILY), STM32F2)
|
|
||||||
cSRCS_$(d) += \
|
|
||||||
usb/descriptors.c \
|
|
||||||
usb/usb.c \
|
|
||||||
usb/usb_callbacks.c \
|
|
||||||
usb/usb_hardware.c \
|
|
||||||
usb/usb_lib/usb_core.c \
|
|
||||||
usb/usb_lib/usb_init.c \
|
|
||||||
usb/usb_lib/usb_int.c \
|
|
||||||
usb/usb_lib/usb_mem.c \
|
|
||||||
usb/usb_lib/usb_regs.c
|
|
||||||
else
|
|
||||||
V=1
|
V=1
|
||||||
cSRCS_$(d) += \
|
cSRCS_$(d) += \
|
||||||
usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c \
|
usbF4/STM32_USB_Device_Library/Core/src/usbd_core.c \
|
||||||
|
@ -69,11 +51,7 @@ else
|
||||||
usbF4/VCP/usbd_usr.c \
|
usbF4/VCP/usbd_usr.c \
|
||||||
usbF4/usb.c \
|
usbF4/usb.c \
|
||||||
usbF4/VCP/misc.c
|
usbF4/VCP/misc.c
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(MCU_FAMILY), STM32F2)
|
|
||||||
cSRCS_$(d) += bkp.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
sSRCS_$(d) := exc.S
|
sSRCS_$(d) := exc.S
|
||||||
|
|
||||||
|
|
|
@ -83,25 +83,29 @@ void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Nonblocking SPI transmit.
|
* @brief Blocking SPI transmit.
|
||||||
* @param dev SPI port to use for transmission
|
* @param dev SPI port to use for transmission
|
||||||
* @param buf Buffer to transmit. The sizeof buf's elements are
|
* @param buf Buffer to transmit. The sizeof buf's elements are
|
||||||
* inferred from dev's data frame format (i.e., are
|
* inferred from dev's data frame format (i.e., are
|
||||||
* correctly treated as 8-bit or 16-bit quantities).
|
* correctly treated as 8-bit or 16-bit quantities).
|
||||||
* @param len Maximum number of elements to transmit.
|
* @param len Maximum number of elements to transmit.
|
||||||
* @return Number of elements transmitted.
|
|
||||||
*/
|
*/
|
||||||
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
|
void spi_tx(spi_dev *dev, void *buf, uint32 len)
|
||||||
uint32 txed = 0;
|
{
|
||||||
uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT;
|
spi_reg_map *regs = dev->regs;
|
||||||
while (spi_is_tx_empty(dev) && (txed < len)) {
|
if ( spi_dff(dev) == SPI_DFF_8_BIT ) {
|
||||||
if (byte_frame) {
|
uint8 * dp8 = (uint8*)buf;
|
||||||
dev->regs->DR = ((const uint8*)buf)[txed++];
|
while ( len-- ) {
|
||||||
} else {
|
while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
|
||||||
dev->regs->DR = ((const uint16*)buf)[txed++];
|
regs->DR = *dp8++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
return txed;
|
uint16 * dp16 = (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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,8 +161,9 @@ void spi_rx_dma_disable(spi_dev *dev) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
|
static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
|
||||||
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
|
#define MASK (SPI_CR1_CRCEN|SPI_CR1_DFF)
|
||||||
spi_peripheral_disable(dev);
|
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
|
||||||
dev->regs->CR1 = cr1_config;
|
if ( (dev->regs->CR1&MASK)!=(cr1_config&MASK) ) spi_peripheral_disable(dev);
|
||||||
spi_peripheral_enable(dev);
|
dev->regs->CR1 = cr1_config;
|
||||||
|
spi_peripheral_enable(dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,31 +213,22 @@ typedef struct spi_dev {
|
||||||
|
|
||||||
void spi_init(spi_dev *dev);
|
void spi_init(spi_dev *dev);
|
||||||
|
|
||||||
struct gpio_dev;
|
|
||||||
/**
|
/**
|
||||||
* @brief Configure GPIO bit modes for use as a SPI port's pins.
|
* @brief Configure GPIO bit modes for use as a SPI port's pins.
|
||||||
*
|
*
|
||||||
* @param dev SPI device
|
* @param dev SPI device
|
||||||
* @param as_master If true, configure as bus master; otherwise, as slave.
|
* @param as_master If true, configure as bus master; otherwise, as slave.
|
||||||
* @param nss_dev NSS pin's GPIO device
|
|
||||||
* @param nss_bit NSS pin's GPIO bit on nss_dev
|
* @param nss_bit NSS pin's GPIO bit on nss_dev
|
||||||
* @param sck_dev SCK pin's GPIO device
|
|
||||||
* @param sck_bit SCK pin's GPIO bit on comm_dev
|
* @param sck_bit SCK pin's GPIO bit on comm_dev
|
||||||
* @param miso_dev MISO pin's GPIO device
|
|
||||||
* @param miso_bit MISO pin's GPIO bit on comm_dev
|
* @param miso_bit MISO pin's GPIO bit on comm_dev
|
||||||
* @param mosi_dev MOSI pin's GPIO device
|
|
||||||
* @param mosi_bit MOSI pin's GPIO bit on comm_dev
|
* @param mosi_bit MOSI pin's GPIO bit on comm_dev
|
||||||
*/
|
*/
|
||||||
extern void spi_config_gpios(spi_dev *dev,
|
extern void spi_config_gpios(spi_dev *dev,
|
||||||
uint8 as_master,
|
uint8 as_master,
|
||||||
struct gpio_dev *nss_dev,
|
uint8 nss_pin,
|
||||||
uint8 nss_bit,
|
uint8 sck_pin,
|
||||||
struct gpio_dev *sck_dev,
|
uint8 miso_pin,
|
||||||
uint8 sck_bit,
|
uint8 mosi_pin);
|
||||||
struct gpio_dev *miso_dev,
|
|
||||||
uint8 miso_bit,
|
|
||||||
struct gpio_dev *mosi_dev,
|
|
||||||
uint8 mosi_bit);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SPI mode configuration.
|
* @brief SPI mode configuration.
|
||||||
|
@ -312,7 +303,7 @@ void spi_slave_enable(spi_dev *dev,
|
||||||
spi_mode mode,
|
spi_mode mode,
|
||||||
uint32 flags);
|
uint32 flags);
|
||||||
|
|
||||||
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len);
|
void spi_tx(spi_dev *dev, void *buf, uint32 len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Call a function on each SPI port
|
* @brief Call a function on each SPI port
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
* @brief STM32F1 SPI/I2S series header.
|
* @brief STM32F1 SPI/I2S series header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIBMAPLE_STM32F1_SPI_H_
|
#ifndef _LIBMAPLE_SPI_F4_H_
|
||||||
#define _LIBMAPLE_STM32F1_SPI_H_
|
#define _LIBMAPLE_SPI_F4_H_
|
||||||
|
|
||||||
#include <libmaple/libmaple_types.h>
|
#include <libmaple/libmaple_types.h>
|
||||||
|
|
||||||
|
@ -62,17 +62,6 @@ extern struct spi_dev *SPI2;
|
||||||
extern struct spi_dev *SPI3;
|
extern struct spi_dev *SPI3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* spi_gpio_cfg(): Backwards compatibility shim to spi_config_gpios() */
|
|
||||||
struct gpio_dev;
|
|
||||||
extern void spi_config_gpios(struct spi_dev*, uint8,
|
|
||||||
struct gpio_dev*, uint8,
|
|
||||||
struct gpio_dev*, uint8,
|
|
||||||
struct gpio_dev*, uint8,
|
|
||||||
struct gpio_dev*, uint8);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,25 +56,21 @@ spi_dev *SPI3 = &spi3;
|
||||||
|
|
||||||
void spi_config_gpios(spi_dev *ignored,
|
void spi_config_gpios(spi_dev *ignored,
|
||||||
uint8 as_master,
|
uint8 as_master,
|
||||||
gpio_dev *nss_dev,
|
uint8 nss_pin,
|
||||||
uint8 nss_bit,
|
uint8 sck_pin,
|
||||||
gpio_dev *sck_dev,
|
uint8 miso_pin,
|
||||||
uint8 sck_bit,
|
uint8 mosi_pin) {
|
||||||
gpio_dev *miso_dev,
|
|
||||||
uint8 miso_bit,
|
|
||||||
gpio_dev *mosi_dev,
|
|
||||||
uint8 mosi_bit) {
|
|
||||||
if (as_master) {
|
if (as_master) {
|
||||||
// gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP);
|
// gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(sck_dev, sck_bit, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(sck_pin, GPIO_AF_OUTPUT_PP);
|
||||||
// gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING);
|
// gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING);
|
||||||
gpio_set_mode(miso_dev, miso_bit, GPIO_AF_INPUT_PD);
|
gpio_set_mode(miso_pin, GPIO_AF_INPUT_PD);
|
||||||
gpio_set_mode(mosi_dev, mosi_bit, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(mosi_pin, GPIO_AF_OUTPUT_PP);
|
||||||
} else {
|
} else {
|
||||||
gpio_set_mode(nss_dev, nss_bit, GPIO_INPUT_FLOATING);
|
gpio_set_mode(nss_pin, GPIO_INPUT_FLOATING);
|
||||||
gpio_set_mode(sck_dev, sck_bit, GPIO_INPUT_FLOATING);
|
gpio_set_mode(sck_pin, GPIO_INPUT_FLOATING);
|
||||||
gpio_set_mode(miso_dev, miso_bit, GPIO_AF_OUTPUT_PP);
|
gpio_set_mode(miso_pin, GPIO_AF_OUTPUT_PP);
|
||||||
gpio_set_mode(mosi_dev, mosi_bit, GPIO_INPUT_FLOATING);
|
gpio_set_mode(mosi_pin, GPIO_INPUT_FLOATING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,69 +138,8 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MCU_STM32F103RB)
|
|
||||||
/* e.g., LeafLabs Maple */
|
|
||||||
|
|
||||||
#define STM32_NR_GPIO_PORTS 4
|
#if defined( STM32F4 )
|
||||||
#define STM32_DELAY_US_MULT 12
|
|
||||||
#define STM32_SRAM_END ((void*)0x20005000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F103ZE)
|
|
||||||
/* e.g., LeafLabs Maple Native */
|
|
||||||
|
|
||||||
#define STM32_NR_GPIO_PORTS 7
|
|
||||||
#define STM32_DELAY_US_MULT 12
|
|
||||||
#define STM32_SRAM_END ((void*)0x20010000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F103CB)
|
|
||||||
/* e.g., LeafLabs Maple Mini */
|
|
||||||
|
|
||||||
/* This STM32_NR_GPIO_PORTS value is not, strictly speaking, true.
|
|
||||||
* But only pins 0 and 1 exist, and they're used for OSC on the
|
|
||||||
* Mini, so we'll live with this for now. */
|
|
||||||
#define STM32_NR_GPIO_PORTS 3
|
|
||||||
#define STM32_DELAY_US_MULT 12
|
|
||||||
#define STM32_SRAM_END ((void*)0x20005000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F103RE)
|
|
||||||
/* e.g., LeafLabs Maple RET6 edition */
|
|
||||||
|
|
||||||
#define STM32_NR_GPIO_PORTS 4
|
|
||||||
#define STM32_DELAY_US_MULT 12
|
|
||||||
#define STM32_SRAM_END ((void*)0x20010000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F103VE)
|
|
||||||
/* e.g., LeafLabs Maple Native */
|
|
||||||
|
|
||||||
#define STM32_NR_GPIO_PORTS 5
|
|
||||||
#define STM32_DELAY_US_MULT 12
|
|
||||||
#define STM32_SRAM_END ((void*)0x20010000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F205VE)
|
|
||||||
#define STM32_TICKS_PER_US 120
|
|
||||||
#define STM32_NR_GPIO_PORTS 5
|
|
||||||
#define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3)
|
|
||||||
#define STM32_SRAM_END ((void*)0x20010000)
|
|
||||||
|
|
||||||
#define NR_GPIO_PORTS STM32_NR_GPIO_PORTS
|
|
||||||
#define DELAY_US_MULT STM32_DELAY_US_MULT
|
|
||||||
|
|
||||||
#elif defined(MCU_STM32F406VG)
|
|
||||||
#define STM32_TICKS_PER_US 168
|
#define STM32_TICKS_PER_US 168
|
||||||
#define STM32_NR_GPIO_PORTS 5
|
#define STM32_NR_GPIO_PORTS 5
|
||||||
#define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3)
|
#define STM32_DELAY_US_MULT (STM32_TICKS_PER_US/3)
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
/* Update only. */
|
/* Update only. */
|
||||||
#define NR_BAS_HANDLERS 1
|
#define NR_BAS_HANDLERS 1
|
||||||
|
|
||||||
static timer_dev timer1 = {
|
timer_dev timer1 = {
|
||||||
.regs = { .adv = TIMER1_BASE },
|
.regs = { .adv = TIMER1_BASE },
|
||||||
.clk_id = RCC_TIMER1,
|
.clk_id = RCC_TIMER1,
|
||||||
.type = TIMER_ADVANCED,
|
.type = TIMER_ADVANCED,
|
||||||
|
@ -53,7 +53,7 @@ static timer_dev timer1 = {
|
||||||
/** Timer 1 device (advanced) */
|
/** Timer 1 device (advanced) */
|
||||||
timer_dev *TIMER1 = &timer1;
|
timer_dev *TIMER1 = &timer1;
|
||||||
|
|
||||||
static timer_dev timer2 = {
|
timer_dev timer2 = {
|
||||||
.regs = { .gen = TIMER2_BASE },
|
.regs = { .gen = TIMER2_BASE },
|
||||||
.clk_id = RCC_TIMER2,
|
.clk_id = RCC_TIMER2,
|
||||||
.type = TIMER_GENERAL,
|
.type = TIMER_GENERAL,
|
||||||
|
@ -62,7 +62,7 @@ static timer_dev timer2 = {
|
||||||
/** Timer 2 device (general-purpose) */
|
/** Timer 2 device (general-purpose) */
|
||||||
timer_dev *TIMER2 = &timer2;
|
timer_dev *TIMER2 = &timer2;
|
||||||
|
|
||||||
static timer_dev timer3 = {
|
timer_dev timer3 = {
|
||||||
.regs = { .gen = TIMER3_BASE },
|
.regs = { .gen = TIMER3_BASE },
|
||||||
.clk_id = RCC_TIMER3,
|
.clk_id = RCC_TIMER3,
|
||||||
.type = TIMER_GENERAL,
|
.type = TIMER_GENERAL,
|
||||||
|
@ -71,7 +71,7 @@ static timer_dev timer3 = {
|
||||||
/** Timer 3 device (general-purpose) */
|
/** Timer 3 device (general-purpose) */
|
||||||
timer_dev *TIMER3 = &timer3;
|
timer_dev *TIMER3 = &timer3;
|
||||||
|
|
||||||
static timer_dev timer4 = {
|
timer_dev timer4 = {
|
||||||
.regs = { .gen = TIMER4_BASE },
|
.regs = { .gen = TIMER4_BASE },
|
||||||
.clk_id = RCC_TIMER4,
|
.clk_id = RCC_TIMER4,
|
||||||
.type = TIMER_GENERAL,
|
.type = TIMER_GENERAL,
|
||||||
|
@ -81,7 +81,7 @@ static timer_dev timer4 = {
|
||||||
timer_dev *TIMER4 = &timer4;
|
timer_dev *TIMER4 = &timer4;
|
||||||
|
|
||||||
#ifdef STM32_HIGH_DENSITY
|
#ifdef STM32_HIGH_DENSITY
|
||||||
static timer_dev timer5 = {
|
timer_dev timer5 = {
|
||||||
.regs = { .gen = TIMER5_BASE },
|
.regs = { .gen = TIMER5_BASE },
|
||||||
.clk_id = RCC_TIMER5,
|
.clk_id = RCC_TIMER5,
|
||||||
.type = TIMER_GENERAL,
|
.type = TIMER_GENERAL,
|
||||||
|
@ -90,7 +90,7 @@ static timer_dev timer5 = {
|
||||||
/** Timer 5 device (general-purpose) */
|
/** Timer 5 device (general-purpose) */
|
||||||
timer_dev *TIMER5 = &timer5;
|
timer_dev *TIMER5 = &timer5;
|
||||||
|
|
||||||
static timer_dev timer6 = {
|
timer_dev timer6 = {
|
||||||
.regs = { .bas = TIMER6_BASE },
|
.regs = { .bas = TIMER6_BASE },
|
||||||
.clk_id = RCC_TIMER6,
|
.clk_id = RCC_TIMER6,
|
||||||
.type = TIMER_BASIC,
|
.type = TIMER_BASIC,
|
||||||
|
@ -99,7 +99,7 @@ static timer_dev timer6 = {
|
||||||
/** Timer 6 device (basic) */
|
/** Timer 6 device (basic) */
|
||||||
timer_dev *TIMER6 = &timer6;
|
timer_dev *TIMER6 = &timer6;
|
||||||
|
|
||||||
static timer_dev timer7 = {
|
timer_dev timer7 = {
|
||||||
.regs = { .bas = TIMER7_BASE },
|
.regs = { .bas = TIMER7_BASE },
|
||||||
.clk_id = RCC_TIMER7,
|
.clk_id = RCC_TIMER7,
|
||||||
.type = TIMER_BASIC,
|
.type = TIMER_BASIC,
|
||||||
|
@ -108,7 +108,7 @@ static timer_dev timer7 = {
|
||||||
/** Timer 7 device (basic) */
|
/** Timer 7 device (basic) */
|
||||||
timer_dev *TIMER7 = &timer7;
|
timer_dev *TIMER7 = &timer7;
|
||||||
|
|
||||||
static timer_dev timer8 = {
|
timer_dev timer8 = {
|
||||||
.regs = { .adv = TIMER8_BASE },
|
.regs = { .adv = TIMER8_BASE },
|
||||||
.clk_id = RCC_TIMER8,
|
.clk_id = RCC_TIMER8,
|
||||||
.type = TIMER_ADVANCED,
|
.type = TIMER_ADVANCED,
|
||||||
|
|
|
@ -113,13 +113,8 @@ typedef struct timer_bas_reg_map {
|
||||||
} timer_bas_reg_map;
|
} timer_bas_reg_map;
|
||||||
|
|
||||||
|
|
||||||
#ifdef STM32F2
|
/** Timer 1 register map base pointer */
|
||||||
/** Timer 1 register map base pointer */
|
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40010000)
|
||||||
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40010000)
|
|
||||||
#else
|
|
||||||
/** Timer 1 register map base pointer */
|
|
||||||
#define TIMER1_BASE ((struct timer_adv_reg_map*)0x40012C00)
|
|
||||||
#endif
|
|
||||||
/** Timer 2 register map base pointer */
|
/** Timer 2 register map base pointer */
|
||||||
#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000)
|
#define TIMER2_BASE ((struct timer_gen_reg_map*)0x40000000)
|
||||||
/** Timer 3 register map base pointer */
|
/** Timer 3 register map base pointer */
|
||||||
|
@ -133,14 +128,8 @@ typedef struct timer_bas_reg_map {
|
||||||
#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000)
|
#define TIMER6_BASE ((struct timer_bas_reg_map*)0x40001000)
|
||||||
/** Timer 7 register map base pointer */
|
/** Timer 7 register map base pointer */
|
||||||
#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400)
|
#define TIMER7_BASE ((struct timer_bas_reg_map*)0x40001400)
|
||||||
|
/** Timer 8 register map base pointer */
|
||||||
#ifdef STM32F2
|
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400)
|
||||||
/** Timer 8 register map base pointer */
|
|
||||||
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40010400)
|
|
||||||
#else
|
|
||||||
/** Timer 8 register map base pointer */
|
|
||||||
#define TIMER8_BASE ((struct timer_adv_reg_map*)0x40013400)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -62,11 +62,7 @@ typedef struct usart_reg_map {
|
||||||
} usart_reg_map;
|
} usart_reg_map;
|
||||||
|
|
||||||
/** USART1 register map base pointer */
|
/** USART1 register map base pointer */
|
||||||
#ifdef STM32F2
|
#define USART1_BASE ((struct usart_reg_map*)0x40011000)
|
||||||
#define USART1_BASE ((struct usart_reg_map*)0x40011000)
|
|
||||||
#else
|
|
||||||
#define USART1_BASE ((struct usart_reg_map*)0x40013800)
|
|
||||||
#endif
|
|
||||||
/** USART2 register map base pointer */
|
/** USART2 register map base pointer */
|
||||||
#define USART2_BASE ((struct usart_reg_map*)0x40004400)
|
#define USART2_BASE ((struct usart_reg_map*)0x40004400)
|
||||||
/** USART3 register map base pointer */
|
/** USART3 register map base pointer */
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "usbd_ioreq.h"
|
#include "usbd_ioreq.h"
|
||||||
#include "usbd_req.h"
|
#include "usbd_req.h"
|
||||||
#include "usbd_desc.h"
|
#include <VCP\usbd_desc.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
#ifndef __USB_CDC_CORE_H_
|
#ifndef __USB_CDC_CORE_H_
|
||||||
#define __USB_CDC_CORE_H_
|
#define __USB_CDC_CORE_H_
|
||||||
|
|
||||||
#include "usbd_ioreq.h"
|
#include <STM32_USB_Device_Library\Core\inc/usbd_ioreq.h>
|
||||||
|
#include <STM32_USB_OTG_Driver\inc\usb_core.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -58,9 +58,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_cdc_core.h"
|
#include <VCP\usb_conf.h>
|
||||||
#include "usbd_desc.h"
|
#include <STM32_USB_Device_Library\Class\cdc\inc\usbd_cdc_core.h>
|
||||||
#include "usbd_req.h"
|
#include <VCP\usbd_desc.h>
|
||||||
|
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
#define __USBD_CORE_H
|
#define __USBD_CORE_H
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_dcd.h"
|
#include <STM32_USB_OTG_Driver/inc/usb_dcd.h>
|
||||||
#include "usbd_def.h"
|
#include "usbd_def.h"
|
||||||
#include "usbd_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#ifndef __USBD_DEF_H
|
#ifndef __USBD_DEF_H
|
||||||
#define __USBD_DEF_H
|
#define __USBD_DEF_H
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_def.h"
|
#include "usbd_def.h"
|
||||||
#include "usbd_core.h"
|
#include "usbd_core.h"
|
||||||
#include "usbd_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_core.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_core.h>
|
||||||
#include "usbd_req.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
|
||||||
#include "usbd_ioreq.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
|
||||||
#include "usb_dcd_int.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
|
||||||
#include "usb_bsp.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_ioreq.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_req.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
|
||||||
#include "usbd_ioreq.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
|
||||||
#include "usbd_desc.h"
|
#include <VCP\usbd_desc.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define __USB_CORE_H__
|
#define __USB_CORE_H__
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
#include "usb_regs.h"
|
#include "usb_regs.h"
|
||||||
#include "usb_defines.h"
|
#include "usb_defines.h"
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define __USB_DEF_H__
|
#define __USB_DEF_H__
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef __USB_OTG__
|
#ifndef __USB_OTG__
|
||||||
#define __USB_OTG__
|
#define __USB_OTG__
|
||||||
|
|
||||||
|
#include "usb_core.h"
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#define __USB_OTG_REGS_H__
|
#define __USB_OTG_REGS_H__
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_conf.h"
|
#include <VCP\usbd_conf.h>
|
||||||
|
#include <libmaple\libmaple_types.h>
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_bsp.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
|
||||||
#include "usb_core.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_core.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_dcd.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_dcd.h>
|
||||||
#include "usb_bsp.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_dcd_int.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
|
||||||
|
|
||||||
typedef int IRQn_Type;
|
typedef int IRQn_Type;
|
||||||
#define __NVIC_PRIO_BITS 4
|
#define __NVIC_PRIO_BITS 4
|
||||||
#define __Vendor_SysTickConfig 1
|
#define __Vendor_SysTickConfig 1
|
||||||
#include <core_cm4.h>
|
#include <VCP\core_cm4.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup USB_OTG_DRIVER
|
/** @addtogroup USB_OTG_DRIVER
|
||||||
|
|
|
@ -141,7 +141,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h> /*!< standard types definitions */
|
#include <stdint.h> /*!< standard types definitions */
|
||||||
#include <core_cmInstr.h> /*!< Core Instruction Access */
|
#include "core_cmInstr.h" /*!< Core Instruction Access */
|
||||||
//#include <core_cmFunc.h> /*!< Core Function Access */
|
//#include <core_cmFunc.h> /*!< Core Function Access */
|
||||||
//#include <core_cm4_simd.h> /*!< Compiler specific SIMD Intrinsics */
|
//#include <core_cm4_simd.h> /*!< Compiler specific SIMD Intrinsics */
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ typedef unsigned char u8;
|
||||||
typedef int IRQn_Type;
|
typedef int IRQn_Type;
|
||||||
#define __NVIC_PRIO_BITS 4
|
#define __NVIC_PRIO_BITS 4
|
||||||
#define __Vendor_SysTickConfig 1
|
#define __Vendor_SysTickConfig 1
|
||||||
#include <core_cm4.h>
|
#include "core_cm4.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
/** @addtogroup STM32F4xx_StdPeriph_Driver
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usb_bsp.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
|
||||||
#include "usbd_conf.h"
|
#include "usbd_conf.h"
|
||||||
#include <gpio.h>
|
#include <libmaple/gpio.h>
|
||||||
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
||||||
#define OTG_FS_IRQn 67
|
#define OTG_FS_IRQn 67
|
||||||
//typedef unsigned char uint8_t;
|
//typedef unsigned char uint8_t;
|
||||||
#include <misc.h>
|
#include "misc.h"
|
||||||
|
|
||||||
//#include "stm32f4_discovery.h"
|
//#include "stm32f4_discovery.h"
|
||||||
|
|
||||||
|
@ -97,10 +97,10 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
|
||||||
{
|
{
|
||||||
// ala42
|
// ala42
|
||||||
#define GPIO_AF_OTG1_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
|
#define GPIO_AF_OTG1_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
|
||||||
gpio_set_mode(GPIOA,11,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
gpio_set_mode(BOARD_USB_DM_PIN,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
||||||
gpio_set_mode(GPIOA,12,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
gpio_set_mode(BOARD_USB_DP_PIN,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
||||||
gpio_set_af_mode(GPIOA,11,GPIO_AF_OTG1_FS) ; // OTG_FS_DM
|
gpio_set_af_mode(BOARD_USB_DM_PIN,GPIO_AF_OTG1_FS) ; // OTG_FS_DM
|
||||||
gpio_set_af_mode(GPIOA,12,GPIO_AF_OTG1_FS) ; // OTG_FS_DP
|
gpio_set_af_mode(BOARD_USB_DP_PIN,GPIO_AF_OTG1_FS) ; // OTG_FS_DP
|
||||||
#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
|
#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
|
||||||
gpio_set_mode(GPIOA, 8,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
gpio_set_mode(GPIOA, 8,GPIO_MODE_AF | GPIO_OTYPE_PP | GPIO_OSPEED_100MHZ);
|
||||||
gpio_set_af_mode(GPIOA, 8,GPIO_AF_OTG1_FS) ; // OTG_FS_SOF
|
gpio_set_af_mode(GPIOA, 8,GPIO_AF_OTG1_FS) ; // OTG_FS_SOF
|
||||||
|
@ -122,10 +122,10 @@ void USB_OTG_BSP_DeInit(USB_OTG_CORE_HANDLE *pdev)
|
||||||
{
|
{
|
||||||
// ala42
|
// ala42
|
||||||
#define GPIO_AF0 ((uint8_t)0) /* OTG_FS Alternate Function mapping */
|
#define GPIO_AF0 ((uint8_t)0) /* OTG_FS Alternate Function mapping */
|
||||||
gpio_set_mode(GPIOA,11, GPIO_MODE_INPUT);
|
gpio_set_mode(BOARD_USB_DM_PIN, GPIO_MODE_INPUT);
|
||||||
gpio_set_mode(GPIOA,12, GPIO_MODE_INPUT);
|
gpio_set_mode(BOARD_USB_DP_PIN, GPIO_MODE_INPUT);
|
||||||
gpio_set_af_mode(GPIOA,11,GPIO_AF0) ; // OTG_FS_DM
|
gpio_set_af_mode(BOARD_USB_DM_PIN,GPIO_AF0) ; // OTG_FS_DM
|
||||||
gpio_set_af_mode(GPIOA,12,GPIO_AF0) ; // OTG_FS_DP
|
gpio_set_af_mode(BOARD_USB_DP_PIN,GPIO_AF0) ; // OTG_FS_DP
|
||||||
#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
|
#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
|
||||||
gpio_set_mode(GPIOA, 8,GPIO_MODE_INPUT);
|
gpio_set_mode(GPIOA, 8,GPIO_MODE_INPUT);
|
||||||
gpio_set_af_mode(GPIOA, 8,GPIO_AF0) ; // OTG_FS_SOF
|
gpio_set_af_mode(GPIOA, 8,GPIO_AF0) ; // OTG_FS_SOF
|
||||||
|
|
|
@ -173,7 +173,9 @@ typedef unsigned char u8;
|
||||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||||
#define __packed __packed
|
#define __packed __packed
|
||||||
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
||||||
|
#ifndef __packed
|
||||||
#define __packed __attribute__ ((__packed__))
|
#define __packed __attribute__ ((__packed__))
|
||||||
|
#endif
|
||||||
#elif defined (__TASKING__) /* TASKING Compiler */
|
#elif defined (__TASKING__) /* TASKING Compiler */
|
||||||
#define __packed __unaligned
|
#define __packed __unaligned
|
||||||
#endif /* __CC_ARM */
|
#endif /* __CC_ARM */
|
||||||
|
@ -206,7 +208,9 @@ typedef unsigned char u8;
|
||||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||||
#define __packed __packed
|
#define __packed __packed
|
||||||
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
||||||
|
#ifndef __packed
|
||||||
#define __packed __attribute__ ((__packed__))
|
#define __packed __attribute__ ((__packed__))
|
||||||
|
#endif
|
||||||
#elif defined (__TASKING__) /* TASKING Compiler */
|
#elif defined (__TASKING__) /* TASKING Compiler */
|
||||||
#define __packed __unaligned
|
#define __packed __unaligned
|
||||||
#endif /* __CC_ARM */
|
#endif /* __CC_ARM */
|
||||||
|
|
|
@ -255,7 +255,7 @@ typedef struct {
|
||||||
|
|
||||||
void systemHardReset(void) {
|
void systemHardReset(void) {
|
||||||
SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE;
|
SCB_TypeDef* rSCB = (SCB_TypeDef *) SCB_BASE;
|
||||||
typedef void (*funcPtr)(void);
|
//typedef void (*funcPtr)(void); // not used
|
||||||
|
|
||||||
/* Reset */
|
/* Reset */
|
||||||
rSCB->AIRCR = (u32)AIRCR_RESET_REQ;
|
rSCB->AIRCR = (u32)AIRCR_RESET_REQ;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
//#include "stm32f4xx.h"
|
//#include "stm32f4xx.h"
|
||||||
|
|
||||||
#include "usbd_cdc_core.h"
|
#include <STM32_USB_Device_Library\Class\cdc\inc\usbd_cdc_core.h>
|
||||||
#include "usbd_conf.h"
|
#include "usbd_conf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
//#include "stm32f4_discovery.h"
|
//#include "stm32f4_discovery.h"
|
||||||
|
#include "usb_conf.h"
|
||||||
|
|
||||||
/** @defgroup USB_CONF_Exported_Defines
|
/** @defgroup USB_CONF_Exported_Defines
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_core.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_core.h>
|
||||||
#include "usbd_desc.h"
|
#include "usbd_desc.h"
|
||||||
#include "usbd_req.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
|
||||||
#include "usbd_conf.h"
|
#include "usbd_conf.h"
|
||||||
#include "usb_regs.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_regs.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#define __USB_DESC_H
|
#define __USB_DESC_H
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_def.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_def.h>
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_usr.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_usr.h>
|
||||||
#include "usbd_ioreq.h"
|
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
|
|
@ -1,27 +1,30 @@
|
||||||
#include "usbd_cdc_core.h"
|
#ifndef _USBF4_USB_H_
|
||||||
#include "usbd_usr.h"
|
#define _USBF4_USB_H_
|
||||||
#include "usbd_desc.h"
|
|
||||||
|
|
||||||
|
#include <STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h>
|
||||||
|
#include <STM32_USB_Device_Library/Core/inc/usbd_usr.h>
|
||||||
|
#include <VCP\usbd_desc.h>
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include <gpio.h>
|
#include <libmaple/gpio.h>
|
||||||
#include <rccF2.h>
|
#include <libmaple/rccF4.h>
|
||||||
#include <usbd_cdc_vcp.h>
|
#include <VCP\usbd_cdc_vcp.h>
|
||||||
|
#include <boards.h>
|
||||||
|
|
||||||
USB_OTG_CORE_HANDLE USB_OTG_dev;
|
USB_OTG_CORE_HANDLE USB_OTG_dev;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void setupUSB (void) {
|
void setupUSB (void)
|
||||||
#define USB_DISC_DEV GPIOD
|
{
|
||||||
#define USB_DISC_PIN 11
|
gpio_set_mode(BOARD_USB_DP_PIN, GPIO_OUTPUT_OD); // ala42
|
||||||
|
|
||||||
gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
|
|
||||||
#ifdef USB_DISC_OD
|
#ifdef USB_DISC_OD
|
||||||
//gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
|
//gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
|
||||||
#else
|
#else
|
||||||
//gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin
|
//gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42
|
gpio_clear_pin(BOARD_USB_DP_PIN); // ala42
|
||||||
delay_us(200000);
|
delay_us(200000);
|
||||||
|
|
||||||
/* setup the apb1 clock for USB */
|
/* setup the apb1 clock for USB */
|
||||||
|
@ -29,7 +32,7 @@ void setupUSB (void) {
|
||||||
//pRCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
//pRCC->APB1ENR |= RCC_APB1ENR_USBEN;
|
||||||
|
|
||||||
/* initialize the usb application */
|
/* initialize the usb application */
|
||||||
gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host
|
gpio_set_pin(BOARD_USB_DP_PIN); // ala42 // presents us to the host
|
||||||
USBD_Init(&USB_OTG_dev,
|
USBD_Init(&USB_OTG_dev,
|
||||||
USB_OTG_FS_CORE_ID,
|
USB_OTG_FS_CORE_ID,
|
||||||
&USR_desc,
|
&USR_desc,
|
||||||
|
@ -93,7 +96,7 @@ RESULT usbPowerOff(void) {
|
||||||
|
|
||||||
void usbDsbISR(void) {};
|
void usbDsbISR(void) {};
|
||||||
|
|
||||||
#include "usb_dcd_int.h"
|
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
|
||||||
void __irq_OTG_FS_IRQHandler(void)
|
void __irq_OTG_FS_IRQHandler(void)
|
||||||
{
|
{
|
||||||
USBD_OTG_ISR_Handler (&USB_OTG_dev);
|
USBD_OTG_ISR_Handler (&USB_OTG_dev);
|
||||||
|
@ -102,3 +105,5 @@ void __irq_OTG_FS_IRQHandler(void)
|
||||||
void x__irq_usbwakeup(void)
|
void x__irq_usbwakeup(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "usb_conf.h"
|
#include <VCP\usb_conf.h>
|
||||||
|
|
||||||
typedef enum _RESULT
|
typedef enum _RESULT
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,7 @@ void throb(void) {
|
||||||
uint32 TOP_CNT = 0x0800;
|
uint32 TOP_CNT = 0x0800;
|
||||||
uint32 i = 0;
|
uint32 i = 0;
|
||||||
|
|
||||||
gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_OUTPUT_PP);
|
gpio_set_mode(ERROR_LED_PIN, GPIO_OUTPUT_PP);
|
||||||
/* Error fade. */
|
/* Error fade. */
|
||||||
while (1) {
|
while (1) {
|
||||||
if (CC == TOP_CNT) {
|
if (CC == TOP_CNT) {
|
||||||
|
@ -143,9 +143,9 @@ void throb(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < CC) {
|
if (i < CC) {
|
||||||
gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1);
|
gpio_set_pin(ERROR_LED_PIN);
|
||||||
} else {
|
} else {
|
||||||
gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0);
|
gpio_clear_pin(ERROR_LED_PIN);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,12 @@
|
||||||
* @brief Miscellaneous utility macros and procedures.
|
* @brief Miscellaneous utility macros and procedures.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
|
|
||||||
#ifndef _UTIL_H_
|
#ifndef _UTIL_H_
|
||||||
#define _UTIL_H_
|
#define _UTIL_H_
|
||||||
|
|
||||||
|
#include "libmaple_types.h"
|
||||||
|
#include "delay.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
* @brief Arduino-style PWM implementation.
|
* @brief Arduino-style PWM implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
#include <libmaple/libmaple_types.h>
|
||||||
#include "timer.h"
|
#include <libmaple/timer.h>
|
||||||
|
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "pwm.h"
|
#include "pwm.h"
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "wirish.h"
|
#include "wirish.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
#ifdef SERIAL_USB
|
||||||
|
|
||||||
#define USB_TIMEOUT 50
|
#define USB_TIMEOUT 50
|
||||||
|
|
||||||
USBSerial::USBSerial(void) {
|
USBSerial::USBSerial(void) {
|
||||||
|
@ -132,7 +134,7 @@ uint8 USBSerial::pending(void) {
|
||||||
return usbGetPending();
|
return usbGetPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 USBSerial::isConnected(void) {
|
USBSerial::operator bool() {
|
||||||
return usbIsConnected() && usbIsConfigured();
|
return usbIsConnected() && usbIsConfigured();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,3 +155,5 @@ void USBSerial::disableBlockingTx(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
USBSerial SerialUSB;
|
USBSerial SerialUSB;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
|
|
||||||
|
#ifdef SERIAL_USB
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Virtual serial terminal.
|
* @brief Virtual serial terminal.
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +59,8 @@ public:
|
||||||
|
|
||||||
uint8 getRTS();
|
uint8 getRTS();
|
||||||
uint8 getDTR();
|
uint8 getDTR();
|
||||||
uint8 isConnected();
|
operator bool();
|
||||||
|
uint8 isConnected() { return (bool) *this; }
|
||||||
uint8 pending();
|
uint8 pending();
|
||||||
|
|
||||||
void enableBlockingTx(void);
|
void enableBlockingTx(void);
|
||||||
|
@ -65,6 +68,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
extern USBSerial SerialUSB;
|
extern USBSerial SerialUSB;
|
||||||
|
#define Serial SerialUSB
|
||||||
|
|
||||||
#endif
|
#else // _USB_SERIAL_H_
|
||||||
|
|
||||||
|
#define Serial Serial1
|
||||||
|
|
||||||
|
#endif // SERIAL_USB
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _USB_SERIAL_H_
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
#define _WIRISH_H_
|
#define _WIRISH_H_
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "libmaple.h"
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "wirish_types.h"
|
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
|
@ -44,10 +44,8 @@
|
||||||
#include "ext_interrupts.h"
|
#include "ext_interrupts.h"
|
||||||
#include "wirish_debug.h"
|
#include "wirish_debug.h"
|
||||||
#include "wirish_math.h"
|
#include "wirish_math.h"
|
||||||
#include "wirish_time.h"
|
|
||||||
#include <wirish_constants.h>
|
#include <wirish_constants.h>
|
||||||
#include "HardwareSPI.h"
|
#include <libmaple/HardwareSerial.h>
|
||||||
#include "HardwareSerial.h"
|
|
||||||
#include "HardwareTimer.h"
|
#include "HardwareTimer.h"
|
||||||
#include "usb_serial.h"
|
#include "usb_serial.h"
|
||||||
|
|
||||||
|
@ -55,9 +53,10 @@
|
||||||
#define HIGH 0x1
|
#define HIGH 0x1
|
||||||
#define LOW 0x0
|
#define LOW 0x0
|
||||||
|
|
||||||
#define true 0x1
|
#ifndef true
|
||||||
#define false 0x0
|
#define true 0x1
|
||||||
|
#define false 0x0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define lowByte(w) ((w) & 0xFF)
|
#define lowByte(w) ((w) & 0xFF)
|
||||||
#define highByte(w) (((w) >> 8) & 0xFF)
|
#define highByte(w) (((w) >> 8) & 0xFF)
|
||||||
|
|
|
@ -28,9 +28,7 @@
|
||||||
* @brief Arduino-compatible ADC implementation.
|
* @brief Arduino-compatible ADC implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libmaple.h"
|
|
||||||
#include "wirish.h"
|
#include "wirish.h"
|
||||||
#include "io.h"
|
|
||||||
|
|
||||||
/* Assumes that the ADC has been initialized and that the pin is set
|
/* Assumes that the ADC has been initialized and that the pin is set
|
||||||
* to INPUT_ANALOG */
|
* to INPUT_ANALOG */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef _WIRING_CONSTANTS_
|
#ifndef _WIRISH_CONSTANTS_H_
|
||||||
#define _WIRING_CONSTANTS_
|
#define _WIRISH_CONSTANTS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _WIRISH_DEBUG_H_
|
||||||
|
#define _WIRISH_DEBUG_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file wirish_debug.h
|
* @file wirish_debug.h
|
||||||
* @brief High level debug port configuration
|
* @brief High level debug port configuration
|
||||||
|
@ -50,5 +53,7 @@ static inline void disableDebugPorts(void) {
|
||||||
* @see disableDebugPorts()
|
* @see disableDebugPorts()
|
||||||
*/
|
*/
|
||||||
static inline void enableDebugPorts(void) {
|
static inline void enableDebugPorts(void) {
|
||||||
afio_cfg_debug_ports(AFIO_DEBUG_FULL_SWJ);
|
afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); //AFIO_DEBUG_FULL_SWJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "wirish.h"
|
#include "wirish.h"
|
||||||
#include "io.h"
|
|
||||||
|
|
||||||
void pinMode(uint8 pin, WiringPinMode mode) {
|
void pinMode(uint8 pin, WiringPinMode mode) {
|
||||||
gpio_pin_mode outputMode;
|
gpio_pin_mode outputMode;
|
||||||
|
@ -72,7 +72,7 @@ void pinMode(uint8 pin, WiringPinMode mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, outputMode);
|
gpio_set_mode(pin, outputMode);
|
||||||
|
|
||||||
if (PIN_MAP[pin].timer_device != NULL) {
|
if (PIN_MAP[pin].timer_device != NULL) {
|
||||||
/* Enable/disable timer channels if we're switching into or
|
/* Enable/disable timer channels if we're switching into or
|
||||||
|
@ -84,48 +84,51 @@ void pinMode(uint8 pin, WiringPinMode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32 digitalRead(uint8 pin) {
|
uint32 digitalRead(uint8 pin)
|
||||||
|
{
|
||||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit) ?
|
return gpio_read_pin(pin) ?
|
||||||
HIGH : LOW;
|
HIGH : LOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
void digitalWrite(uint8 pin, uint8 val) {
|
void digitalWrite(uint8 pin, uint8 val)
|
||||||
|
{
|
||||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, val);
|
gpio_write_pin(pin, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void togglePin(uint8 pin) {
|
void togglePin(uint8 pin)
|
||||||
|
{
|
||||||
if (pin >= BOARD_NR_GPIO_PINS) {
|
if (pin >= BOARD_NR_GPIO_PINS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_toggle_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit);
|
gpio_toggle_pin(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUTTON_DEBOUNCE_DELAY 1
|
#define BUTTON_DEBOUNCE_DELAY 1
|
||||||
|
|
||||||
uint8 isButtonPressed() {
|
uint8 isButtonPressed(uint8_t button) {
|
||||||
if (digitalRead(BOARD_BUTTON_PIN)) {
|
if (digitalRead(button)) {
|
||||||
delay(BUTTON_DEBOUNCE_DELAY);
|
delay(BUTTON_DEBOUNCE_DELAY);
|
||||||
while (digitalRead(BOARD_BUTTON_PIN))
|
while (digitalRead(button))
|
||||||
;
|
;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 waitForButtonPress(uint32 timeout) {
|
uint8 waitForButtonPress(uint8_t button, uint32 timeout) {
|
||||||
uint32 start = millis();
|
uint32 start = millis();
|
||||||
uint32 time;
|
uint32 time;
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
while (!isButtonPressed())
|
while (!isButtonPressed(button))
|
||||||
;
|
;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -136,6 +139,6 @@ uint8 waitForButtonPress(uint32 timeout) {
|
||||||
time - start > timeout) {
|
time - start > timeout) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} while (!isButtonPressed());
|
} while (!isButtonPressed(button));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
* @brief Includes <math.h>; provides Arduino-compatible math routines.
|
* @brief Includes <math.h>; provides Arduino-compatible math routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WIRING_MATH_H_
|
#ifndef _WIRISH_MATH_H_
|
||||||
#define _WIRING_MATH_H_
|
#define _WIRISH_MATH_H_
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
* @brief Delay implementation.
|
* @brief Delay implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libmaple.h"
|
#include <libmaple/libmaple.h>
|
||||||
#include "systick.h"
|
#include <libmaple/systick.h>
|
||||||
#include "wirish_time.h"
|
#include "wirish_time.h"
|
||||||
#include "delay.h"
|
#include <libmaple/delay.h>
|
||||||
|
|
||||||
void delay(unsigned long ms) {
|
void delay(unsigned long ms) {
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
|
@ -32,10 +32,9 @@
|
||||||
#ifndef __WIRISH_TIME_H_
|
#ifndef __WIRISH_TIME_H_
|
||||||
#define __WIRISH_TIME_H_
|
#define __WIRISH_TIME_H_
|
||||||
|
|
||||||
#include "libmaple.h"
|
|
||||||
#include "nvic.h"
|
|
||||||
#include "systick.h"
|
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
#include <libmaple/nvic.h>
|
||||||
|
#include <libmaple/systick.h>
|
||||||
|
|
||||||
#define US_PER_MS 1000
|
#define US_PER_MS 1000
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,13 @@
|
||||||
* @brief Wirish library type definitions.
|
* @brief Wirish library type definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libmaple_types.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "adc.h"
|
|
||||||
|
|
||||||
#ifndef _WIRISH_TYPES_H_
|
#ifndef _WIRISH_TYPES_H_
|
||||||
#define _WIRISH_TYPES_H_
|
#define _WIRISH_TYPES_H_
|
||||||
|
|
||||||
|
#include <libmaple/gpio_def.h>
|
||||||
|
#include <libmaple/timer.h>
|
||||||
|
#include <libmaple/adc.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalid stm32_pin_info adc_channel value.
|
* Invalid stm32_pin_info adc_channel value.
|
||||||
* @see stm32_pin_info
|
* @see stm32_pin_info
|
||||||
|
@ -48,16 +47,28 @@
|
||||||
* @brief Stores STM32-specific information related to a given Maple pin.
|
* @brief Stores STM32-specific information related to a given Maple pin.
|
||||||
* @see PIN_MAP
|
* @see PIN_MAP
|
||||||
*/
|
*/
|
||||||
|
#ifdef BOARD_generic_f407v
|
||||||
|
// restructure members to build consecutive pairs
|
||||||
typedef struct stm32_pin_info {
|
typedef struct stm32_pin_info {
|
||||||
gpio_dev *gpio_device; /**< Maple pin's GPIO device */
|
const gpio_dev * gpio_device; /**< Maple pin's GPIO device */
|
||||||
timer_dev *timer_device; /**< Pin's timer device, if any. */
|
timer_dev * timer_device; /**< Pin's timer device, if any. */
|
||||||
const adc_dev *adc_device; /**< ADC device, if any. */
|
|
||||||
uint8 gpio_bit; /**< Pin's GPIO port bit. */
|
|
||||||
uint8 timer_channel; /**< Timer channel, or 0 if none. */
|
uint8 timer_channel; /**< Timer channel, or 0 if none. */
|
||||||
uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */
|
uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */
|
||||||
uint8 filler;
|
const adc_dev *adc_device; /**< ADC device, if any. */
|
||||||
} stm32_pin_info;
|
} stm32_pin_info;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef struct stm32_pin_info {
|
||||||
|
const gpio_dev *gpio_device; /**< Maple pin's GPIO device */
|
||||||
|
timer_dev *timer_device; /**< Pin's timer device, if any. */
|
||||||
|
const adc_dev *adc_device; /**< ADC device, if any. */
|
||||||
|
uint8 timer_channel; /**< Timer channel, or 0 if none. */
|
||||||
|
uint8 adc_channel; /**< Pin ADC channel, or ADCx if none. */
|
||||||
|
} stm32_pin_info;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable attribute, instructs the linker to place the marked
|
* Variable attribute, instructs the linker to place the marked
|
||||||
* variable in Flash instead of RAM. */
|
* variable in Flash instead of RAM. */
|
||||||
|
|
|
@ -7,3 +7,4 @@ paragraph=SPI for STM32F4
|
||||||
category=Communication
|
category=Communication
|
||||||
url=
|
url=
|
||||||
architectures=STM32F4
|
architectures=STM32F4
|
||||||
|
maintainer=
|
|
@ -40,9 +40,9 @@
|
||||||
#include "wirish.h"
|
#include "wirish.h"
|
||||||
#include "boards.h"
|
#include "boards.h"
|
||||||
|
|
||||||
//#include "HardwareSerial.h"
|
#define DMA_TIMEOUT 100
|
||||||
|
|
||||||
#if CYCLES_PER_MICROSECOND != 72
|
#if CYCLES_PER_MICROSECOND != 168
|
||||||
/* TODO [0.2.0?] something smarter than this */
|
/* TODO [0.2.0?] something smarter than this */
|
||||||
#warning "Unexpected clock speed; SPI frequency calculation will be incorrect"
|
#warning "Unexpected clock speed; SPI frequency calculation will be incorrect"
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,77 +91,115 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SPIClass::SPIClass(uint32 spi_num) {
|
SPIClass::SPIClass(uint32 spi_num) {
|
||||||
|
|
||||||
|
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
|
||||||
|
|
||||||
|
|
||||||
switch (spi_num) {
|
switch (spi_num) {
|
||||||
#if BOARD_NR_SPI >= 1
|
#if BOARD_NR_SPI >= 1
|
||||||
case 1:
|
case 1:
|
||||||
this->spi_d = SPI1;
|
_currentSetting->spi_d = SPI1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if BOARD_NR_SPI >= 2
|
#if BOARD_NR_SPI >= 2
|
||||||
case 2:
|
case 2:
|
||||||
this->spi_d = SPI2;
|
_currentSetting->spi_d = SPI2;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if BOARD_NR_SPI >= 3
|
#if BOARD_NR_SPI >= 3
|
||||||
case 3:
|
case 3:
|
||||||
this->spi_d = SPI3;
|
_currentSetting->spi_d = SPI3;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//pinMode(BOARD_SPI_DEFAULT_SS,OUTPUT);
|
// Init things specific to each SPI device
|
||||||
|
// clock divider setup is a bit of hack, and needs to be improved at a later date.
|
||||||
clockDivider = SPI_BAUD_PCLK_DIV_16;
|
/*****************************************************************************/
|
||||||
dataMode = SPI_MODE0;
|
// DMA / Channel / Stream
|
||||||
|
// Rx Tx
|
||||||
|
// SPI1: 2 / 3 / 0 (2) - 2 / 3 / 3 (5)
|
||||||
|
// SPI2: 1 / 0 / 3 - 1 / 0 / 4
|
||||||
|
// SPI3: 1 / 0 / 0 (2) - 1 / 0 / 5 (7)
|
||||||
|
/*****************************************************************************/
|
||||||
|
_settings[0].spi_d = SPI1;
|
||||||
|
_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
|
||||||
|
#ifdef SPI_DMA
|
||||||
|
_settings[0].spiDmaDev = DMA2;
|
||||||
|
_settings[0].spiDmaChannel = DMA_CH3;
|
||||||
|
_settings[0].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2
|
||||||
|
_settings[0].spiTxDmaStream = DMA_STREAM3; // alternative: DMA_STREAM5
|
||||||
|
#endif
|
||||||
|
_settings[1].spi_d = SPI2;
|
||||||
|
_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
|
||||||
|
#ifdef SPI_DMA
|
||||||
|
_settings[1].spiDmaDev = DMA1;
|
||||||
|
_settings[1].spiDmaChannel = DMA_CH0;
|
||||||
|
_settings[1].spiRxDmaStream = DMA_STREAM3; // alternative: -
|
||||||
|
_settings[1].spiTxDmaStream = DMA_STREAM4; // alternative: -
|
||||||
|
#endif
|
||||||
|
#if BOARD_NR_SPI >= 3
|
||||||
|
_settings[2].spi_d = SPI3;
|
||||||
|
_settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock);
|
||||||
|
#ifdef SPI_DMA
|
||||||
|
_settings[2].spiDmaDev = DMA1;
|
||||||
|
_settings[2].spiDmaChannel = DMA_CH0;
|
||||||
|
_settings[2].spiRxDmaStream = DMA_STREAM0; // alternative: DMA_STREAM2
|
||||||
|
_settings[2].spiTxDmaStream = DMA_STREAM5; // alternative: DMA_STREAM7
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up/tear down
|
* Set up/tear down
|
||||||
*/
|
*/
|
||||||
|
void SPIClass::updateSettings(void) {
|
||||||
|
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS);
|
||||||
|
#ifdef SPI_DEBUG
|
||||||
|
Serial.print("spi_master_enable("); Serial.print(_currentSetting->clockDivider); Serial.print(","); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
||||||
|
#endif
|
||||||
|
spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);
|
||||||
|
}
|
||||||
|
|
||||||
void SPIClass::begin(void) {
|
void SPIClass::begin(void) {
|
||||||
|
spi_init(_currentSetting->spi_d);
|
||||||
uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
|
configure_gpios(_currentSetting->spi_d, 1);
|
||||||
spi_init(spi_d);
|
updateSettings();
|
||||||
configure_gpios(spi_d, 1);
|
#ifdef SPI_USE_DMA_BUFFER
|
||||||
#ifdef SPI_DEBUG
|
dmaSendBufferInit();
|
||||||
Serial.print("spi_master_enable("); Serial.print(clockDivider); Serial.print(","); Serial.print(dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
#endif
|
||||||
#endif
|
//Serial.println("SPI class begin - end");
|
||||||
spi_master_enable(spi_d, (spi_baud_rate)clockDivider, (spi_mode)dataMode, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::beginSlave(void) {
|
void SPIClass::beginSlave(void) {
|
||||||
if (dataMode >= 4) {
|
spi_init(_currentSetting->spi_d);
|
||||||
ASSERT(0);
|
configure_gpios(_currentSetting->spi_d, 0);
|
||||||
return;
|
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY);
|
||||||
}
|
|
||||||
uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE);
|
|
||||||
spi_init(spi_d);
|
|
||||||
configure_gpios(spi_d, 0);
|
|
||||||
#ifdef SPI_DEBUG
|
#ifdef SPI_DEBUG
|
||||||
Serial.print("spi_slave_enable("); Serial.print(dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
||||||
#endif
|
#endif
|
||||||
spi_slave_enable(spi_d, (spi_mode)dataMode, flags);
|
spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::end(void) {
|
void SPIClass::end(void) {
|
||||||
if (!spi_is_enabled(this->spi_d)) {
|
if (!spi_is_enabled(_currentSetting->spi_d)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Follows RM0008's sequence for disabling a SPI in master/slave
|
// Follows RM0008's sequence for disabling a SPI in master/slave
|
||||||
// full duplex mode.
|
// full duplex mode.
|
||||||
while (spi_is_rx_nonempty(this->spi_d)) {
|
while (spi_is_rx_nonempty(_currentSetting->spi_d)) {
|
||||||
// FIXME [0.1.0] remove this once you have an interrupt based driver
|
// FIXME [0.1.0] remove this once you have an interrupt based driver
|
||||||
volatile uint16 rx __attribute__((unused)) = spi_rx_reg(this->spi_d);
|
volatile uint16 rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d);
|
||||||
}
|
}
|
||||||
while (!spi_is_tx_empty(this->spi_d))
|
while (!spi_is_tx_empty(_currentSetting->spi_d))
|
||||||
;
|
;
|
||||||
while (spi_is_busy(this->spi_d))
|
while (spi_is_busy(_currentSetting->spi_d))
|
||||||
;
|
;
|
||||||
spi_peripheral_disable(this->spi_d);
|
spi_peripheral_disable(_currentSetting->spi_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Roger Clark added 3 functions */
|
/* Roger Clark added 3 functions */
|
||||||
|
@ -170,8 +208,9 @@ void SPIClass::setClockDivider(uint32_t clockDivider)
|
||||||
#ifdef SPI_DEBUG
|
#ifdef SPI_DEBUG
|
||||||
Serial.print("Clock divider set to "); Serial.println(clockDivider);
|
Serial.print("Clock divider set to "); Serial.println(clockDivider);
|
||||||
#endif
|
#endif
|
||||||
this->clockDivider = clockDivider;
|
_currentSetting->clockDivider = clockDivider;
|
||||||
this->begin();
|
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR);
|
||||||
|
_currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setBitOrder(BitOrder bitOrder)
|
void SPIClass::setBitOrder(BitOrder bitOrder)
|
||||||
|
@ -179,8 +218,10 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
|
||||||
#ifdef SPI_DEBUG
|
#ifdef SPI_DEBUG
|
||||||
Serial.print("Bit order set to "); Serial.println(bitOrder);
|
Serial.print("Bit order set to "); Serial.println(bitOrder);
|
||||||
#endif
|
#endif
|
||||||
this->bitOrder = bitOrder;
|
_currentSetting->bitOrder = bitOrder;
|
||||||
this->begin();
|
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST);
|
||||||
|
if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST;
|
||||||
|
_currentSetting->spi_d->regs->CR1 = cr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly.
|
/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly.
|
||||||
|
@ -189,11 +230,11 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
|
||||||
*/
|
*/
|
||||||
void SPIClass::setDataSize(uint32 datasize)
|
void SPIClass::setDataSize(uint32 datasize)
|
||||||
{
|
{
|
||||||
uint32 cr1 = this->spi_d->regs->CR1;
|
_currentSetting->dataSize = datasize;
|
||||||
datasize &= SPI_CR1_DFF;
|
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF);
|
||||||
cr1 &= ~(SPI_CR1_DFF);
|
uint8 en = spi_is_enabled(_currentSetting->spi_d);
|
||||||
cr1 |= datasize;
|
spi_peripheral_disable(_currentSetting->spi_d);
|
||||||
this->spi_d->regs->CR1 = cr1;
|
_currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t dataMode)
|
void SPIClass::setDataMode(uint8_t dataMode)
|
||||||
|
@ -212,13 +253,11 @@ SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge
|
||||||
On the STM32 it appears to be
|
On the STM32 it appears to be
|
||||||
|
|
||||||
bit 1 - CPOL : Clock polarity
|
bit 1 - CPOL : Clock polarity
|
||||||
|
|
||||||
(This bit should not be changed when communication is ongoing)
|
(This bit should not be changed when communication is ongoing)
|
||||||
0 : CLK to 0 when idle
|
0 : CLK to 0 when idle
|
||||||
1 : CLK to 1 when idle
|
1 : CLK to 1 when idle
|
||||||
|
|
||||||
bit 0 - CPHA : Clock phase
|
bit 0 - CPHA : Clock phase
|
||||||
|
|
||||||
(This bit should not be changed when communication is ongoing)
|
(This bit should not be changed when communication is ongoing)
|
||||||
0 : The first clock transition is the first data capture edge
|
0 : The first clock transition is the first data capture edge
|
||||||
1 : The second clock transition is the first data capture edge
|
1 : The second clock transition is the first data capture edge
|
||||||
|
@ -228,44 +267,32 @@ If someone finds this is not the case or sees a logic error with this let me kno
|
||||||
#ifdef SPI_DEBUG
|
#ifdef SPI_DEBUG
|
||||||
Serial.print("Data mode set to "); Serial.println(dataMode);
|
Serial.print("Data mode set to "); Serial.println(dataMode);
|
||||||
#endif
|
#endif
|
||||||
this->dataMode = dataMode;
|
_currentSetting->dataMode = dataMode;
|
||||||
this->begin();
|
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA);
|
||||||
}
|
_currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA));
|
||||||
|
}
|
||||||
|
|
||||||
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
|
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
|
||||||
{
|
{
|
||||||
#ifdef SPI_DEBUG
|
#ifdef SPI_DEBUG
|
||||||
Serial.println("SPIClass::beginTransaction");
|
Serial.println("SPIClass::beginTransaction");
|
||||||
#endif
|
#endif
|
||||||
//_SSPin=pin;
|
|
||||||
//pinMode(_SSPin,OUTPUT);
|
|
||||||
//digitalWrite(_SSPin,LOW);
|
|
||||||
setBitOrder(settings.bitOrder);
|
setBitOrder(settings.bitOrder);
|
||||||
setDataMode(settings.dataMode);
|
setDataMode(settings.dataMode);
|
||||||
setClockDivider(determine_baud_rate(spi_d, settings.clock));
|
setDataSize(settings.dataSize);
|
||||||
|
setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
|
||||||
begin();
|
begin();
|
||||||
#if 0
|
}
|
||||||
// code from SAM core
|
|
||||||
uint8_t mode = interruptMode;
|
void SPIClass::beginTransactionSlave(SPISettings settings)
|
||||||
if (mode > 0) {
|
{
|
||||||
if (mode < 16) {
|
#ifdef SPI_DEBUG
|
||||||
if (mode & 1) PIOA->PIO_IDR = interruptMask[0];
|
Serial.println(F("SPIClass::beginTransactionSlave"));
|
||||||
if (mode & 2) PIOB->PIO_IDR = interruptMask[1];
|
#endif
|
||||||
if (mode & 4) PIOC->PIO_IDR = interruptMask[2];
|
setBitOrder(settings.bitOrder);
|
||||||
if (mode & 8) PIOD->PIO_IDR = interruptMask[3];
|
setDataMode(settings.dataMode);
|
||||||
} else {
|
setDataSize(settings.dataSize);
|
||||||
interruptSave = interruptsStatus();
|
beginSlave();
|
||||||
noInterrupts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
|
|
||||||
bitOrder[ch] = settings.border;
|
|
||||||
SPI_ConfigureNPCS(spi, ch, settings.config);
|
|
||||||
//setBitOrder(pin, settings.border);
|
|
||||||
//setDataMode(pin, settings.datamode);
|
|
||||||
//setClockDivider(pin, settings.clockdiv);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::endTransaction(void)
|
void SPIClass::endTransaction(void)
|
||||||
|
@ -295,131 +322,154 @@ void SPIClass::endTransaction(void)
|
||||||
* I/O
|
* I/O
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8 SPIClass::read(void) {
|
uint16 SPIClass::read(void)
|
||||||
uint8 buf[1];
|
{
|
||||||
this->read(buf, 1);
|
while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ;
|
||||||
return buf[0];
|
return (uint16)spi_rx_reg(_currentSetting->spi_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::read(uint8 *buf, uint32 len) {
|
void SPIClass::read(uint8 *buf, uint32 len)
|
||||||
uint32 rxed = 0;
|
{
|
||||||
while (rxed < len) {
|
if ( len == 0 ) return;
|
||||||
while (!spi_is_rx_nonempty(this->spi_d))
|
spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it.
|
||||||
;
|
spi_reg_map * regs = _currentSetting->spi_d->regs;
|
||||||
buf[rxed++] = (uint8)spi_rx_reg(this->spi_d);
|
// start sequence: write byte 0
|
||||||
}
|
regs->DR = 0x00FF; // write the first byte
|
||||||
|
// main loop
|
||||||
|
while ( (--len) ) {
|
||||||
|
while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag
|
||||||
|
noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data
|
||||||
|
regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
|
||||||
|
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register
|
||||||
|
*buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag.
|
||||||
|
interrupts(); // let systick do its job
|
||||||
|
}
|
||||||
|
// read remaining last byte
|
||||||
|
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register
|
||||||
|
*buf++ = (uint8)(regs->DR); // read and store the received byte
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::write(uint16 data) {
|
void SPIClass::write(uint16 data)
|
||||||
#ifdef SPI_DEBUG
|
{
|
||||||
// Serial.print("SPIClass::write("); Serial.print(data); Serial.println(")");
|
|
||||||
#endif
|
|
||||||
// this->write(&data, 1);
|
|
||||||
|
|
||||||
/* Added for 16bit data Victor Perez. Roger Clark
|
/* Added for 16bit data Victor Perez. Roger Clark
|
||||||
* Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, * by taking the Tx code from transfer(byte)
|
* Improved speed by just directly writing the single byte to the SPI data reg and wait for completion,
|
||||||
* The original method, of calling write(*data, length) .
|
* by taking the Tx code from transfer(byte)
|
||||||
* This almost doubles the speed of this function.
|
* This almost doubles the speed of this function.
|
||||||
*/
|
*/
|
||||||
|
spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
|
||||||
spi_tx_reg(this->spi_d, data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//void SPIClass::write(uint8 byte) {
|
void SPIClass::write(uint16 data, uint32 n)
|
||||||
// this->write(&byte, 1);
|
{
|
||||||
|
// Added by stevstrong: Repeatedly send same data by the specified number of times
|
||||||
/* Roger Clark
|
spi_reg_map * regs = _currentSetting->spi_d->regs;
|
||||||
* Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, * by taking the Tx code from transfer(byte)
|
while ( (n--)>0 ) {
|
||||||
* The original method, of calling write(*data, length) .
|
regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
|
||||||
* This almost doubles the speed of this function.
|
while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty
|
||||||
*/
|
}
|
||||||
|
while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning
|
||||||
// spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
|
||||||
// while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
|
||||||
// while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
|
||||||
//}
|
|
||||||
|
|
||||||
void SPIClass::write(const uint8 *data, uint32 length) {
|
|
||||||
#ifdef SPI_DEBUG
|
|
||||||
Serial.print("SPIClass::write(data, "); Serial.print(length); Serial.println(")");
|
|
||||||
#endif
|
|
||||||
uint32 txed = 0;
|
|
||||||
while (txed < length) {
|
|
||||||
txed += spi_tx(this->spi_d, data + txed, length - txed);
|
|
||||||
}
|
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "4. After writing the last data item into the SPI_DR register, wait until TXE=1 ..."
|
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... then wait until BSY=0, this indicates that the transmission of the last data is complete."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::transfer(uint8 byte) const {
|
void SPIClass::write(void *data, uint32 length)
|
||||||
#ifdef SPI_DEBUG
|
{
|
||||||
// Serial.print("SPIClass::transfer("); Serial.print(byte); Serial.println(")");
|
spi_dev * spi_d = _currentSetting->spi_d;
|
||||||
#endif
|
spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words
|
||||||
uint8 b;
|
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
while (spi_is_rx_nonempty(this->spi_d) == 0); // "4. Wait until RXNE=1 ..."
|
|
||||||
b = spi_rx_reg(this->spi_d); // "... and read the last received data."
|
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 SPIClass::transfer(uint8 byte) const
|
||||||
|
{
|
||||||
|
spi_dev * spi_d = _currentSetting->spi_d;
|
||||||
|
spi_rx_reg(spi_d); // read any previous data
|
||||||
|
spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register
|
||||||
|
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
|
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
|
return (uint8)spi_rx_reg(spi_d); // "... and read the last received data."
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SPIClass::transfer16(uint16_t wr_data) const
|
||||||
|
{
|
||||||
|
spi_dev * spi_d = _currentSetting->spi_d;
|
||||||
|
spi_rx_reg(spi_d); // read any previous data
|
||||||
|
spi_tx_reg(spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
||||||
|
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
|
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
|
return (uint16)spi_rx_reg(spi_d); // "... and read the last received data."
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SPI_DMA
|
||||||
/* Roger Clark and Victor Perez, 2015
|
/* Roger Clark and Victor Perez, 2015
|
||||||
* Performs a DMA SPI transfer with at least a receive buffer.
|
* Performs a DMA SPI transfer with at least a receive buffer.
|
||||||
* If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer.
|
* If a TX buffer is not provided, FF is sent over and over for the length of the transfer.
|
||||||
* On exit TX buffer is not modified, and RX buffer cotains the received data.
|
* On exit TX buffer is not modified, and RX buffer contains the received data.
|
||||||
* Still in progress.
|
* Still in progress.
|
||||||
*/
|
*/
|
||||||
uint8 SPIClass::dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length) {
|
uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length)
|
||||||
|
{
|
||||||
if (length == 0) return 0;
|
if (length == 0) return 0;
|
||||||
uint8 b;
|
|
||||||
if (spi_is_rx_nonempty(this->spi_d) == 1) b = spi_rx_reg(this->spi_d); //Clear the RX buffer in case a byte is waiting on it.
|
uint8 b = 0;
|
||||||
dma1_ch3_Active=true;
|
|
||||||
dma_init(DMA1);
|
dma_init(_currentSetting->spiDmaDev);
|
||||||
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
|
// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
spi_rx_dma_enable(SPI1);
|
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
|
||||||
dma_setup_transfer(DMA1, DMA_CH2, &SPI1->regs->DR, DMA_SIZE_8BITS,
|
dma_setup_transfer( _currentSetting->spiDmaDev,
|
||||||
receiveBuf, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_TRNS_CMPLT));// receive buffer DMA
|
_currentSetting->spiRxDmaStream,
|
||||||
dma_set_num_transfers(DMA1, DMA_CH2, length);
|
_currentSetting->spiDmaChannel,
|
||||||
|
dma_bit_size,
|
||||||
|
&_currentSetting->spi_d->regs->DR, // peripheral address
|
||||||
|
receiveBuf, // memory bank 0 address
|
||||||
|
NULL, // memory bank 1 address
|
||||||
|
(DMA_MINC_MODE | DMA_FROM_PER | DMA_PRIO_VERY_HIGH) // flags
|
||||||
|
);
|
||||||
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, length);
|
||||||
|
dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream, 0);
|
||||||
|
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream);
|
||||||
|
|
||||||
// TX
|
// TX
|
||||||
spi_tx_dma_enable(SPI1);
|
uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM); // | DMA_TRNS_CMPLT);
|
||||||
if (!transmitBuf) {
|
if ( transmitBuf==0 ) {
|
||||||
static uint8_t ff = 0XFF;
|
static uint8_t ff = 0XFF;
|
||||||
transmitBuf = &ff;
|
transmitBuf = &ff;
|
||||||
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
|
flags &= ~((uint32)DMA_MINC_MODE); // remove increment mode
|
||||||
transmitBuf, DMA_SIZE_8BITS, (DMA_FROM_MEM | DMA_TRNS_CMPLT));// Transmit FF repeatedly
|
|
||||||
}
|
}
|
||||||
else {
|
dma_setup_transfer( _currentSetting->spiDmaDev,
|
||||||
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
|
_currentSetting->spiTxDmaStream,
|
||||||
transmitBuf, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT));// Transmit buffer DMA
|
_currentSetting->spiDmaChannel,
|
||||||
}
|
dma_bit_size,
|
||||||
dma_set_num_transfers(DMA1, DMA_CH3, length);
|
&_currentSetting->spi_d->regs->DR, // peripheral address
|
||||||
|
transmitBuf, // memory bank 0 address
|
||||||
dma_enable(DMA1, DMA_CH2);// enable receive
|
NULL, // memory bank 1 address
|
||||||
dma_enable(DMA1, DMA_CH3);// enable transmit
|
flags
|
||||||
|
);
|
||||||
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, length);
|
||||||
|
dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, 0);
|
||||||
|
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
|
||||||
|
// software enable sequence, see AN4031, chapter 4.3
|
||||||
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream);// enable receive
|
||||||
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);// enable transmit
|
||||||
|
spi_rx_reg(_currentSetting->spi_d); //Clear the RX buffer in case a byte is waiting on it.
|
||||||
|
spi_rx_dma_enable(_currentSetting->spi_d);
|
||||||
|
spi_tx_dma_enable(_currentSetting->spi_d); // must be the last enable to avoid DMA error flag
|
||||||
|
|
||||||
// while (dma1_ch3_Active);
|
|
||||||
// if (receiveBuf) {
|
|
||||||
uint32_t m = millis();
|
uint32_t m = millis();
|
||||||
while (dma1_ch3_Active) {
|
while ((b = dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
|
||||||
if ((millis() - m) > 100) {
|
if ( b&(DMA_ISR_TEIF|DMA_ISR_DMEIF|DMA_ISR_FEIF) ) { b = 1; break; } // break on any error flag
|
||||||
dma1_ch3_Active = 0;
|
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
||||||
b = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (b & DMA_ISR_TCIF) b = 0;
|
||||||
|
|
||||||
// }
|
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
// software disable sequence, see AN4031, chapter 4.1
|
||||||
dma_disable(DMA1, DMA_CH3);
|
spi_tx_dma_disable(_currentSetting->spi_d);
|
||||||
dma_disable(DMA1, DMA_CH2);
|
spi_rx_dma_disable(_currentSetting->spi_d);
|
||||||
spi_rx_dma_disable(SPI1);
|
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream);
|
||||||
spi_tx_dma_disable(SPI1);
|
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,56 +477,45 @@ uint8 SPIClass::dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length
|
||||||
* Performs a DMA SPI send using a TX buffer.
|
* Performs a DMA SPI send using a TX buffer.
|
||||||
* On exit TX buffer is not modified.
|
* On exit TX buffer is not modified.
|
||||||
* Still in progress.
|
* Still in progress.
|
||||||
|
* 2016 - stevstrong - reworked to automatically detect bit size from SPI setting
|
||||||
*/
|
*/
|
||||||
uint8 SPIClass::dmaSend(uint8 *transmitBuf, uint16 length, bool minc) {
|
uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
|
||||||
|
{
|
||||||
if (length == 0) return 0;
|
if (length == 0) return 0;
|
||||||
uint32 flags = ((DMA_MINC_MODE * minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
|
uint8 b = 0;
|
||||||
uint8 b;
|
dma_init(_currentSetting->spiDmaDev);
|
||||||
dma1_ch3_Active=true;
|
|
||||||
dma_init(DMA1);
|
|
||||||
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
|
|
||||||
|
|
||||||
// TX
|
// TX
|
||||||
spi_tx_dma_enable(SPI1);
|
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==SPI_DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
|
||||||
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
|
dma_setup_transfer( _currentSetting->spiDmaDev,
|
||||||
transmitBuf, DMA_SIZE_8BITS, flags);// Transmit buffer DMA
|
_currentSetting->spiTxDmaStream,
|
||||||
dma_set_num_transfers(DMA1, DMA_CH3, length);
|
_currentSetting->spiDmaChannel,
|
||||||
dma_enable(DMA1, DMA_CH3);// enable transmit
|
dma_bit_size,
|
||||||
|
&_currentSetting->spi_d->regs->DR, // peripheral address
|
||||||
while (dma1_ch3_Active);
|
transmitBuf, // memory bank 0 address
|
||||||
while (spi_is_rx_nonempty(this->spi_d) == 0); // "4. Wait until RXNE=1 ..."
|
NULL, // memory bank 1 address
|
||||||
b = spi_rx_reg(this->spi_d); // "... and read the last received data."
|
( (DMA_MINC_MODE*minc) | DMA_FROM_MEM ) //| DMA_TRNS_CMPLT ) // flags
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
);// Transmit buffer DMA
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, length);
|
||||||
dma_disable(DMA1, DMA_CH3);
|
dma_set_fifo_flags(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream, 0);
|
||||||
spi_tx_dma_disable(SPI1);
|
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
|
||||||
return b;
|
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);// enable transmit
|
||||||
}
|
spi_tx_dma_enable(_currentSetting->spi_d);
|
||||||
|
|
||||||
uint8 SPIClass::dmaSend(uint16 *transmitBuf, uint16 length, bool minc) {
|
uint32_t m = millis();
|
||||||
if (length == 0) return 0;
|
while ((b = dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
|
||||||
uint32 flags = ((DMA_MINC_MODE * minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
|
if ( b&(DMA_ISR_TEIF|DMA_ISR_DMEIF|DMA_ISR_FEIF) ) { b = 1; break; } // break on any error flag
|
||||||
uint8 b;
|
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
|
||||||
dma1_ch3_Active=true;
|
}
|
||||||
dma_init(DMA1);
|
if (b & DMA_ISR_TCIF) b = 0;
|
||||||
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
|
|
||||||
|
|
||||||
// TX
|
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||||
spi_tx_dma_enable(SPI1);
|
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||||
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_16BITS,
|
spi_tx_dma_disable(_currentSetting->spi_d);
|
||||||
transmitBuf, DMA_SIZE_16BITS, flags);// Transmit buffer DMA
|
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
|
||||||
dma_set_num_transfers(DMA1, DMA_CH3, length);
|
return b;
|
||||||
dma_enable(DMA1, DMA_CH3);// enable transmit
|
|
||||||
|
|
||||||
while (dma1_ch3_Active);
|
|
||||||
while (spi_is_rx_nonempty(this->spi_d) == 0); // "4. Wait until RXNE=1 ..."
|
|
||||||
b = spi_rx_reg(this->spi_d); // "... and read the last received data."
|
|
||||||
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
|
||||||
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
|
||||||
dma_disable(DMA1, DMA_CH3);
|
|
||||||
spi_tx_dma_disable(SPI1);
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SPIClass::attachInterrupt(void) {
|
void SPIClass::attachInterrupt(void) {
|
||||||
|
@ -492,19 +531,19 @@ void SPIClass::detachInterrupt(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8 SPIClass::misoPin(void) {
|
uint8 SPIClass::misoPin(void) {
|
||||||
return dev_to_spi_pins(this->spi_d)->miso;
|
return dev_to_spi_pins(_currentSetting->spi_d)->miso;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::mosiPin(void) {
|
uint8 SPIClass::mosiPin(void) {
|
||||||
return dev_to_spi_pins(this->spi_d)->mosi;
|
return dev_to_spi_pins(_currentSetting->spi_d)->mosi;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::sckPin(void) {
|
uint8 SPIClass::sckPin(void) {
|
||||||
return dev_to_spi_pins(this->spi_d)->sck;
|
return dev_to_spi_pins(_currentSetting->spi_d)->sck;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::nssPin(void) {
|
uint8 SPIClass::nssPin(void) {
|
||||||
return dev_to_spi_pins(this->spi_d)->nss;
|
return dev_to_spi_pins(_currentSetting->spi_d)->nss;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -512,18 +551,13 @@ uint8 SPIClass::nssPin(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8 SPIClass::send(uint8 data) {
|
uint8 SPIClass::send(uint8 data) {
|
||||||
uint8 buf[] = {data};
|
this->write(data);
|
||||||
return this->send(buf, 1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::send(uint8 *buf, uint32 len) {
|
uint8 SPIClass::send(uint8 *buf, uint32 len) {
|
||||||
uint32 txed = 0;
|
this->write(buf, len);
|
||||||
uint8 ret = 0;
|
return len;
|
||||||
while (txed < len) {
|
|
||||||
this->write(buf[txed++]);
|
|
||||||
ret = this->read();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 SPIClass::recv(void) {
|
uint8 SPIClass::recv(void) {
|
||||||
|
@ -585,29 +619,26 @@ static void configure_gpios(spi_dev *dev, bool as_master) {
|
||||||
if(dev->clk_id <= RCC_SPI2) {
|
if(dev->clk_id <= RCC_SPI2) {
|
||||||
if(nssi) {
|
if(nssi) {
|
||||||
if(!as_master) {
|
if(!as_master) {
|
||||||
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 5);
|
gpio_set_af_mode(pins->nss, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 5);
|
gpio_set_af_mode(pins->sck, 5);
|
||||||
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 5);
|
gpio_set_af_mode(pins->miso, 5);
|
||||||
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 5);
|
gpio_set_af_mode(pins->mosi, 5);
|
||||||
} else {
|
} else {
|
||||||
if(nssi) {
|
if(nssi) {
|
||||||
if(!as_master) {
|
if(!as_master) {
|
||||||
gpio_set_af_mode(nssi->gpio_device, scki->gpio_bit, 6);
|
gpio_set_af_mode(pins->nss, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gpio_set_af_mode(scki->gpio_device, scki->gpio_bit, 6);
|
gpio_set_af_mode(pins->sck, 6);
|
||||||
gpio_set_af_mode(misoi->gpio_device, misoi->gpio_bit, 6);
|
gpio_set_af_mode(pins->miso, 6);
|
||||||
gpio_set_af_mode(mosii->gpio_device, mosii->gpio_bit, 6);
|
gpio_set_af_mode(pins->mosi, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit,
|
spi_config_gpios(dev, as_master, pins->nss, pins->sck, pins->miso, pins->mosi);
|
||||||
scki->gpio_device, scki->gpio_bit,
|
|
||||||
misoi->gpio_device, misoi->gpio_bit,
|
|
||||||
mosii->gpio_device, mosii->gpio_bit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const spi_baud_rate baud_rates[8] __FLASH__ = {
|
static const spi_baud_rate baud_rates[8] __FLASH__ = {
|
||||||
|
@ -634,6 +665,8 @@ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
|
||||||
{
|
{
|
||||||
case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
|
case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
|
||||||
case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
|
case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
|
||||||
|
case RCC_AHB1: break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
clock /= 2;
|
clock /= 2;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -646,4 +679,3 @@ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
|
||||||
|
|
||||||
|
|
||||||
//SPIClass SPI(3);
|
//SPIClass SPI(3);
|
||||||
|
|
||||||
|
|
|
@ -34,18 +34,16 @@
|
||||||
/* TODO [0.1.0] Remove deprecated methods. */
|
/* TODO [0.1.0] Remove deprecated methods. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _LIB_SPI_H_
|
||||||
#ifndef _SPI_H_INCLUDED
|
#define _LIB_SPI_H_
|
||||||
#define _SPI_H_INCLUDED
|
|
||||||
|
|
||||||
#include <libmaple/libmaple_types.h>
|
#include <libmaple/libmaple_types.h>
|
||||||
#include <libmaple/spi.h>
|
#include <libmaple/spi.h>
|
||||||
#include <libmaple/dma.h>
|
#include <libmaple/dma.h>
|
||||||
|
|
||||||
#include <boards.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <wirish.h>
|
#include <wirish.h>
|
||||||
|
|
||||||
|
#define SPI_DMA
|
||||||
|
|
||||||
// SPI_HAS_TRANSACTION means SPI has
|
// SPI_HAS_TRANSACTION means SPI has
|
||||||
// - beginTransaction()
|
// - beginTransaction()
|
||||||
// - endTransaction()
|
// - endTransaction()
|
||||||
|
@ -96,34 +94,61 @@
|
||||||
#define SPI_MODE2 SPI_MODE_2
|
#define SPI_MODE2 SPI_MODE_2
|
||||||
#define SPI_MODE3 SPI_MODE_3
|
#define SPI_MODE3 SPI_MODE_3
|
||||||
|
|
||||||
|
#define SPI_DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT
|
||||||
|
#define SPI_DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT
|
||||||
|
|
||||||
class SPISettings {
|
class SPISettings {
|
||||||
public:
|
public:
|
||||||
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
||||||
if (__builtin_constant_p(clock)) {
|
if (__builtin_constant_p(clock)) {
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
init_AlwaysInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT);
|
||||||
} else {
|
} else {
|
||||||
init_MightInline(clock, bitOrder, dataMode);
|
init_MightInline(clock, bitOrder, dataMode, SPI_DATA_SIZE_8BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
|
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
|
||||||
private:
|
if (__builtin_constant_p(clock)) {
|
||||||
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
|
||||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
} else {
|
||||||
|
init_MightInline(clock, bitOrder, dataMode, dataSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
|
SPISettings(uint32_t clock) {
|
||||||
|
if (__builtin_constant_p(clock)) {
|
||||||
|
init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT);
|
||||||
|
} else {
|
||||||
|
init_MightInline(clock, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, SPI_DATA_SIZE_8BIT); }
|
||||||
|
private:
|
||||||
|
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
|
||||||
|
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
|
||||||
|
}
|
||||||
|
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__)) {
|
||||||
this->clock = clock;
|
this->clock = clock;
|
||||||
this->bitOrder = bitOrder;
|
this->bitOrder = bitOrder;
|
||||||
this->dataMode = dataMode;
|
this->dataMode = dataMode;
|
||||||
|
this->dataSize = dataSize;
|
||||||
}
|
}
|
||||||
uint32_t clock;
|
uint32_t clock;
|
||||||
BitOrder bitOrder;
|
BitOrder bitOrder;
|
||||||
uint8_t dataMode;
|
uint8_t dataMode;
|
||||||
|
uint32_t dataSize;
|
||||||
|
|
||||||
|
spi_dev *spi_d;
|
||||||
|
uint32_t clockDivider;
|
||||||
|
|
||||||
|
#ifdef SPI_DMA
|
||||||
|
dma_dev* spiDmaDev;
|
||||||
|
dma_channel spiDmaChannel;
|
||||||
|
dma_stream spiRxDmaStream, spiTxDmaStream;
|
||||||
|
#endif
|
||||||
|
|
||||||
friend class SPIClass;
|
friend class SPIClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
volatile static bool dma1_ch3_Active;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wirish SPI interface.
|
* @brief Wirish SPI interface.
|
||||||
*
|
*
|
||||||
|
@ -133,18 +158,11 @@ volatile static bool dma1_ch3_Active;
|
||||||
class SPIClass {
|
class SPIClass {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param spiPortNumber Number of the SPI port to manage.
|
* @param spiPortNumber Number of the SPI port to manage.
|
||||||
*/
|
*/
|
||||||
SPIClass(uint32 spiPortNumber);
|
SPIClass(uint32 spiPortNumber);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up/tear down
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
|
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
|
||||||
|
@ -175,6 +193,8 @@ public:
|
||||||
void beginTransaction(uint8_t pin, SPISettings settings);
|
void beginTransaction(uint8_t pin, SPISettings settings);
|
||||||
void endTransaction(void);
|
void endTransaction(void);
|
||||||
|
|
||||||
|
void beginTransactionSlave(SPISettings settings);
|
||||||
|
|
||||||
void setClockDivider(uint32_t clockDivider);
|
void setClockDivider(uint32_t clockDivider);
|
||||||
void setBitOrder(BitOrder bitOrder);
|
void setBitOrder(BitOrder bitOrder);
|
||||||
void setDataMode(uint8_t dataMode);
|
void setDataMode(uint8_t dataMode);
|
||||||
|
@ -195,40 +215,40 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the next unread byte.
|
* @brief Return the next unread byte/word.
|
||||||
*
|
*
|
||||||
* If there is no unread byte waiting, this function will block
|
* If there is no unread byte/word waiting, this function will block
|
||||||
* until one is received.
|
* until one is received.
|
||||||
*/
|
*/
|
||||||
uint8 read(void);
|
uint16 read(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read length bytes, storing them into buffer.
|
* @brief Read length bytes, storing them into buffer.
|
||||||
* @param buffer Buffer to store received bytes into.
|
* @param buffer Buffer to store received bytes into.
|
||||||
* @param length Number of bytes to store in buffer. This
|
* @param length Number of bytes to store in buffer. This
|
||||||
* function will block until the desired number of
|
* function will block until the desired number of
|
||||||
* bytes have been read.
|
* bytes have been read.
|
||||||
*/
|
*/
|
||||||
void read(uint8 *buffer, uint32 length);
|
void read(uint8 *buffer, uint32 length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Transmit a byte.
|
* @brief Transmit one byte/word.
|
||||||
* @param data Byte to transmit.
|
|
||||||
*/
|
|
||||||
// void write(uint8 data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit a half word.
|
|
||||||
* @param data to transmit.
|
* @param data to transmit.
|
||||||
*/
|
*/
|
||||||
void write(uint16 data);
|
void write(uint16 data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Transmit multiple bytes.
|
* @brief Transmit one byte/word a specified number of times.
|
||||||
* @param buffer Bytes to transmit.
|
* @param data to transmit.
|
||||||
* @param length Number of bytes in buffer to transmit.
|
|
||||||
*/
|
*/
|
||||||
void write(const uint8 *buffer, uint32 length);
|
void write(uint16 data, uint32 n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transmit multiple bytes/words.
|
||||||
|
* @param buffer Bytes/words to transmit.
|
||||||
|
* @param length Number of bytes/words in buffer to transmit.
|
||||||
|
*/
|
||||||
|
void write(void * buffer, uint32 length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Transmit a byte, then return the next unread byte.
|
* @brief Transmit a byte, then return the next unread byte.
|
||||||
|
@ -239,9 +259,12 @@ public:
|
||||||
* @return Next unread byte.
|
* @return Next unread byte.
|
||||||
*/
|
*/
|
||||||
uint8 transfer(uint8 data) const;
|
uint8 transfer(uint8 data) const;
|
||||||
|
uint16_t transfer16(uint16_t data) const;
|
||||||
|
|
||||||
|
#ifdef SPI_DMA
|
||||||
/**
|
/**
|
||||||
* @brief Sets up a DMA Transfer for "length" bytes.
|
* @brief Sets up a DMA Transfer for "length" bytes.
|
||||||
|
* The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
|
||||||
*
|
*
|
||||||
* This function transmits and receives to buffers.
|
* This function transmits and receives to buffers.
|
||||||
*
|
*
|
||||||
|
@ -249,30 +272,19 @@ public:
|
||||||
* @param receiveBuf buffer Bytes to save received data.
|
* @param receiveBuf buffer Bytes to save received data.
|
||||||
* @param length Number of bytes in buffer to transmit.
|
* @param length Number of bytes in buffer to transmit.
|
||||||
*/
|
*/
|
||||||
uint8 dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length);
|
uint8 dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets up a DMA Transmit for bytes.
|
* @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode.
|
||||||
|
* The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting.
|
||||||
*
|
*
|
||||||
* This function transmits and does not care about the RX fifo.
|
* This function only transmits and does not care about the RX fifo.
|
||||||
*
|
|
||||||
* @param transmitBuf buffer Bytes to transmit,
|
|
||||||
* @param length Number of bytes in buffer to transmit.
|
|
||||||
* @param minc Set to use Memory Increment mode, clear to use Circular mode.
|
|
||||||
*/
|
|
||||||
uint8 dmaSend(uint8 *transmitBuf, uint16 length, bool minc = 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sets up a DMA Transmit for half words.
|
|
||||||
* SPI PERFIPHERAL MUST BE SET TO 16 BIT MODE BEFORE
|
|
||||||
*
|
|
||||||
* This function transmits and does not care about the RX fifo.
|
|
||||||
*
|
*
|
||||||
* @param data buffer half words to transmit,
|
* @param data buffer half words to transmit,
|
||||||
* @param length Number of bytes in buffer to transmit.
|
* @param length Number of bytes in buffer to transmit.
|
||||||
* @param minc Set to use Memory Increment mode (default if blank), clear to use Circular mode.
|
|
||||||
*/
|
*/
|
||||||
uint8 dmaSend(uint16 *transmitBuf, uint16 length, bool minc = 1);
|
uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pin accessors
|
* Pin accessors
|
||||||
|
@ -304,7 +316,24 @@ public:
|
||||||
* @brief Get a pointer to the underlying libmaple spi_dev for
|
* @brief Get a pointer to the underlying libmaple spi_dev for
|
||||||
* this HardwareSPI instance.
|
* this HardwareSPI instance.
|
||||||
*/
|
*/
|
||||||
spi_dev* c_dev(void) { return this->spi_d; }
|
spi_dev* c_dev(void) { return _currentSetting->spi_d; }
|
||||||
|
|
||||||
|
|
||||||
|
spi_dev *dev(){ return _currentSetting->spi_d;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the number of the SPI peripheral to be used by
|
||||||
|
* this HardwareSPI instance.
|
||||||
|
*
|
||||||
|
* @param spi_num Number of the SPI port. 1-2 in low density devices
|
||||||
|
* or 1-3 in high density devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setModule(int spi_num)
|
||||||
|
{
|
||||||
|
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -- The following methods are deprecated --------------------------- */
|
/* -- The following methods are deprecated --------------------------- */
|
||||||
|
|
||||||
|
@ -338,26 +367,13 @@ public:
|
||||||
*/
|
*/
|
||||||
uint8 recv(void);
|
uint8 recv(void);
|
||||||
|
|
||||||
spi_dev *dev(){ return spi_d;}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SPISettings _settings[BOARD_NR_SPI];
|
||||||
static inline void DMA1_CH3_Event() {
|
SPISettings *_currentSetting;
|
||||||
dma1_ch3_Active = 0;
|
|
||||||
// dma_disable(DMA1, DMA_CH3);
|
void updateSettings(void);
|
||||||
// dma_disable(DMA1, DMA_CH2);
|
|
||||||
|
|
||||||
// To Do. Need to wait for
|
|
||||||
}
|
|
||||||
spi_dev *spi_d;
|
|
||||||
uint8_t _SSPin;
|
|
||||||
uint32_t clockDivider;
|
|
||||||
uint8_t dataMode;
|
|
||||||
BitOrder bitOrder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern SPIClass SPI; // needed bx SdFat(EX) lib
|
||||||
|
|
||||||
extern SPIClass SPI;//(1);// dummy params
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue