Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UITDSP_ADDA_Example2
Revision 1:e997f4e94491, committed 2015-03-16
- Comitter:
- MikamiUitOpen
- Date:
- Mon Mar 16 23:59:49 2015 +0000
- Parent:
- 0:46d099dfd9d6
- Commit message:
- 2
Changed in this revision
--- a/ADC_BuiltIn.cpp Sat Mar 14 06:49:49 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-//------------------------------------------------------
-// Class for ADC using TIM2 trigger
-// To get bit definition for register in
-// peripheral, see "stm32f401xe.h"
-//
-// 2015/03/14, Copyright (c) 2014 MIKAMI, Naoki
-//------------------------------------------------------
-
-#include "ADC_BuiltIn.hpp"
-
-namespace Mikami
-{
- ADC_BuiltIn::ADC_BuiltIn(PinName pin1, int frequency,
- PinName pin2, PinName pin3)
- : adc_(pin1), myAdc_(ADC1)
- {
- myAdc_->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // External Trigger on the rising edge
- | ADC_EXTERNALTRIGCONV_T2_TRGO // Use Timer2 TRGO event
- | ADC_CR2_ADON; // Enable ADC
-
- ch1_ = GetChannelNumber(pin1);
- if (pin2 != NC)
- {
- adc2_ = new AnalogIn(pin2);
- ch2_ = GetChannelNumber(pin2);
- }
- if (pin3 != NC)
- {
- adc3_ = new AnalogIn(pin3);
- ch3_ = GetChannelNumber(pin3);
- }
- SetTim2(frequency);
- Select1stChannel();
- }
-
- // Extract channel number
- uint8_t ADC_BuiltIn::GetChannelNumber(PinName pin)
- {
- uint8_t ch = 0;
- if ((pin & 0x30) == 0x00) ch = pin;
- if ((pin & 0x30) == 0x10) ch = (pin & 0x01) + 8;
- if ((pin & 0x30) == 0x20) ch = (pin & 0x07) + 10;
- return ch;
- }
-
- void ADC_BuiltIn::SetTim2(int frequency)
- {
- __TIM2_CLK_ENABLE(); // Supply clock, See "stm32f4xx_hal_rcc.h"
-
- SystemCoreClockUpdate(); // Update core clock (for F411RE)
- // See system_stm32f4xx.h
- TIM_TypeDef* myTim = TIM2;
-
- myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out
- myTim->ARR = SystemCoreClock/frequency - 1; // Auto-reload
- myTim->PSC = 0; // Prescaler
- myTim->CR1 = TIM_CR1_CEN; // Enable TIM2
- }
-}
-
--- a/ADC_BuiltIn.hpp Sat Mar 14 06:49:49 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-//------------------------------------------------------
-// Class for ADC using TIM2 trigger -- Header
-//
-// 2015/03/14, Copyright (c) 2015 MIKAMI, Naoki
-//------------------------------------------------------
-
-#ifndef ADC_BUILTIN_HPP
-#define ADC_BUILTIN_HPP
-
-#include "mbed.h"
-
-namespace Mikami
-{
- class ADC_BuiltIn
- {
- private:
- // Following object of AnalogIn class will be
- // initialized by menber initializer
- AnalogIn adc_;
- // Following two objects of AnalogIn class will be
- // initailized by regular executable statements
- AnalogIn* adc2_;
- AnalogIn* adc3_;
-
- // Channel of ADC1
- uint8_t ch1_, ch2_, ch3_;
-
- // Set timer to generate sampling pulse for ADC
- void SetTim2(int frequency);
-
- // Exctract channel number
- uint8_t GetChannelNumber(PinName);
-
- // for inhibition of copy constructor
- ADC_BuiltIn(const ADC_BuiltIn&);
- // for inhibition of substitute operator
- ADC_BuiltIn& operator=(const ADC_BuiltIn&);
-
- protected:
- // for normalize
- static const float AMP_ = 1.0f/2048.0f;
-
- ADC_TypeDef* const myAdc_;
-
- // Wait until completion of AD conversion
- void WaitDone()
- { while((myAdc_->SR & ADC_SR_EOC) == RESET); }
-
- public:
-
- // Constructor
- // pin1: Pin Name for input as A0, A1, etc.
- // frequency: Sampling frequency
- // pin2: If use 2nd channel set this parameter
- // pin3: If use 3rd channel set this parameter
- ADC_BuiltIn(PinName pin1, int frequency,
- PinName pin2 = NC, PinName pin3 = NC);
-
- // Read ADC with waiting, range: [0, 0x0FFF]
- virtual uint16_t Read_u16()
- {
- WaitDone();
- return myAdc_->DR;
- }
-
- // Read ADC with waiting, range: [-1.0f, 1.0f]
- virtual float Read()
- {
- WaitDone();
- return AMP_*((int16_t)myAdc_->DR - 2048);
- }
-
- // Select channel
- void Select1stChannel() { myAdc_->SQR3 = ch1_; }
- void Select2ndChannel() { myAdc_->SQR3 = ch2_; }
- void Select3rdChannel() { myAdc_->SQR3 = ch3_; }
-
- // Software start
- virtual void SoftStart()
- { myAdc_->CR2 |= ADC_CR2_SWSTART; }
-
- uint32_t ReadSQR3() { return myAdc_->SQR3; }
- };
-}
-#endif // ADC_BUILTIN_HPP
-
--- a/ADC_Interrupt.hpp Sat Mar 14 06:49:49 2015 +0000
+++ b/ADC_Interrupt.hpp Mon Mar 16 23:59:49 2015 +0000
@@ -1,17 +1,17 @@
//------------------------------------------------------
-// Derived class of ADC_Base for use interrupt
+// Derived class of InternalADC for use interrupt
//
-// 2015/03/14, Copyright (c) 2015 MIKAMI, Naoki
+// 2015/01/27, Copyright (c) 2015 MIKAMI, Naoki
//------------------------------------------------------
#ifndef ADC_INTERRUPT_HPP
#define ADC_INTERRUPT_HPP
-#include "ADC_BuiltIn.hpp"
+#include "InternalADC.hpp"
namespace Mikami
{
- class ADC_Intr : public ADC_BuiltIn
+ class ADC_Intr : public InternalADC
{
private:
// for inhibition of copy constructor
@@ -20,10 +20,9 @@
ADC_Intr& operator=(const ADC_Intr&);
public:
- ADC_Intr(PinName pin1, int frequency,
- PinName pin2 = NC, PinName pin3 = NC)
- : ADC_BuiltIn(pin1, frequency, pin2, pin3)
- { myAdc_->CR1 |= ADC_CR1_EOCIE; } // Interrupt enable
+ ADC_Intr(PinName pin1, PinName pin2 = NC, PinName pin3 = NC)
+ : InternalADC(pin1, pin2, pin3)
+ { myAdc_->CR1 |= ADC_CR1_EOCIE; } // EOC interrupt enable
// Set interrupt vector and enable IRQ of ADC
void SetIntrVec(void (*Func)())
@@ -37,7 +36,7 @@
{ return myAdc_->DR; }
// Read ADC, range: [0, 0x0FFF]
- virtual uint16_t ReadWait_u16()
+ uint16_t ReadWait_u16()
{
WaitDone();
return myAdc_->DR;
@@ -55,7 +54,7 @@
}
// Software start with disable IRQ
- virtual void SoftStart()
+ void SoftStartDisableIRQ()
{
NVIC_DisableIRQ(ADC_IRQn);
myAdc_->CR2 |= ADC_CR2_SWSTART;
@@ -63,3 +62,4 @@
};
}
#endif // ADC_INTERRUPT_HPP
+
--- a/DAC_MCP4921.cpp Sat Mar 14 06:49:49 2015 +0000
+++ b/DAC_MCP4921.cpp Mon Mar 16 23:59:49 2015 +0000
@@ -1,17 +1,17 @@
-//------------------------------------------------------
-// Class for single DAC in MCP4921
+//--------------------------------------------------------------
+// Class for DAC MCP4921
//
-// 2015/02/02, Copyright (c) 2015 MIKAMI, Naoki
-//------------------------------------------------------
+// 2015/02/18, Copyright (c) 2015 MIKAMI, Naoki
+//--------------------------------------------------------------
+#include "InterruptManager.h"
#include "DAC_MCP4921.hpp"
namespace Mikami
{
DAC_MCP4921::DAC_MCP4921(PinName mosi, PinName sclk,
PinName cs, PinName ldac)
- : spi_(mosi, NC, sclk),
- ld_(ldac, 0), mySpi_((SPI_TypeDef*)NULL)
+ : spi_(mosi, NC, sclk), ld_(ldac, 0)
{
if ( (mosi == PA_7) || (mosi == PB_5) ) mySpi_ = SPI1;
if ( (mosi == PB_15) || (mosi == PC_3) ) mySpi_ = SPI2;
@@ -27,10 +27,16 @@
mySpi_->CR1 += SPI_CR1_BR_0;
#endif // __STM32F411xE_H
- // timer prescaler is set same value of boud rate for SPI
- uint16_t psc = (2 << ((mySpi_->CR1 >> 3) & 0x07)) - 1;
- if (mySpi_ != SPI1) psc = (psc + 1)*2 - 1;
- ss_ = new Tim4_ss(psc, 19, cs);
+ cs_ = new DigitalOut(cs, 1);
+
+ mySpi_->CR2 |= SPI_CR2_RXNEIE; // Enable SPI RX buffer not empty interrupt
+
+ IRQn_Type irq = SPI1_IRQn;
+ if (mySpi_ == SPI2) irq = SPI2_IRQn;
+ if (mySpi_ == SPI3) irq = SPI3_IRQn;
+
+ NVIC_SetVector(irq, (uint32_t)Isr); // See "cmsis_nvic.h"
+ NVIC_EnableIRQ(irq); // See "core_cm4.h"
}
void DAC_MCP4921::ScfClockTim3(uint32_t clock, PinName pin)
@@ -38,7 +44,7 @@
if ( (pin != PA_6) && (pin != PB_4) && (pin != PB_5) &&
(pin != PC_6) && (pin != PC_7) && (pin != PC_8) && (pin != PC_9) )
{
- fprintf(stderr, "\r\nIllegal pin name in DAC_MCP4921::ScfClockTim3()\r\n");
+ fprintf(stderr, "\r\nIllegal pin name in DAC_MCP4922::ScfClockTim3()\r\n");
while (true) {}
}
@@ -56,4 +62,8 @@
if (pin == PC_9)
TIM3->CCR4 = (TIM3->ARR + 1)/2;
}
+
+ DigitalOut* DAC_MCP4921::cs_;
+ SPI_TypeDef* DAC_MCP4921::mySpi_;
}
+
--- a/DAC_MCP4921.hpp Sat Mar 14 06:49:49 2015 +0000
+++ b/DAC_MCP4921.hpp Mon Mar 16 23:59:49 2015 +0000
@@ -1,29 +1,28 @@
-//------------------------------------------------------
-// Class for single DAC in MCP4921 -- Header
-// Fast version
+//--------------------------------------------------------------
+// Class for DAC MCP4921 -- Header
+// This class can be also used for MCP4922 (only channel A)
//
-// Default pin assign
+// Default pin assign
// D11 SPI Master Out Slave In
// D13 SPI Serial Clock
-// D10 SPI Slave Select ----------------------- TIM4
+// D10 SPI Slave Select
// D12 to MCP4921 LDAC pin
// D9 clock for Switched-capacitor filter ---- TIM3
//
-// Argument cs in constructor must be output of TIM4,
-// i.e. D10(PB_6), PB_7, D15(PB_8), or D14(PB_9)
+// Argument "cs" in constructor can be used for any pin
+// corresponding to DigitalOut class in mbed
//
-// Argument pin in function ScfClockTim3() can be
-// PA_6(D12), PB_4(D5), PC_6, PB_5(D4), PC_7(D9),
-// PC_8, or PC_9
+// Argument "pin" in member function ScfClockTim3() can be set
+// PA_6(D12), PB_4(D5), PC_6, PB_5(D4), PC_7(D9),
+// PC_8, or PC_9
//
-// 2015/02/02, Copyright (c) 2015 MIKAMI, Naoki
-//------------------------------------------------------
+// 2015/01/31, Copyright (c) 2015 MIKAMI, Naoki
+//--------------------------------------------------------------
#ifndef DAC_MCP4921_HPP
#define DAC_MCP4921_HPP
#include "mbed.h"
-#include "tim4_slaveSelect.hpp"
namespace Mikami
{
@@ -42,7 +41,6 @@
{
if (value < -1.0f) value = -1.0f;
if (value > 1.0f) value = 1.0f;
-
WriteDac((uint16_t)((value + 1.0f)*2047));
}
@@ -60,27 +58,27 @@
// Check busy
bool IsBusy()
- { return (mySpi_->SR & SPI_SR_BSY) == SPI_SR_BSY; }
+ { return (mySpi_->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY; }
// Little wait
void Wait()
- { __NOP(); __NOP(); __NOP(); }
-
+ { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); }
+
// Set clock for switched-capacitor filter
void ScfClockTim3(uint32_t clock, PinName pin = D9);
protected:
- void SlaveSelect() { ss_->SlaveSelect(); }
+ void SlaveSelect() { *cs_ = 0; }
void WriteSpi(uint16_t value) { mySpi_->DR = value; }
private:
SPI spi_; // SPI object of mbed
- Tim4_ss* ss_;
DigitalOut ld_; // for LDAC
+ static DigitalOut* cs_;
// Pointer of I2C
- SPI_TypeDef* mySpi_;
-
+ static SPI_TypeDef* mySpi_;
+
// for inhibition of copy constructor
DAC_MCP4921(const DAC_MCP4921&);
// for inhibition of substitute operator
@@ -93,6 +91,14 @@
SlaveSelect();
WriteSpi(value | 0x3000);
}
+
+ // ISR for RXNE interrupt of SPI
+ static void Isr()
+ {
+ *cs_ = 1;
+ uint16_t value = mySpi_->DR; // Clear RXNE
+ }
};
}
#endif // DAC_MCP4921_HPP
+
--- a/DAC_MCP4922.hpp Sat Mar 14 06:49:49 2015 +0000
+++ b/DAC_MCP4922.hpp Mon Mar 16 23:59:49 2015 +0000
@@ -29,7 +29,7 @@
protected:
void SetCR(DAC dac) { wcr_ = dac | 0x3000; }
-
+
private:
uint16_t wcr_; // write command register
@@ -48,4 +48,3 @@
};
}
#endif // DAC_MCP4922_HPP
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/InternalADC.cpp Mon Mar 16 23:59:49 2015 +0000
@@ -0,0 +1,33 @@
+//------------------------------------------------------
+// Class for Internal ADC using Ticker for trigger
+// To get bit definition for registers in
+// peripheral, see "stm32f401xe.h"
+//
+// 2015/01/27, Copyright (c) 2015 MIKAMI, Naoki
+//------------------------------------------------------
+
+#include "InternalADC.hpp"
+
+namespace Mikami
+{
+ InternalADC::InternalADC(PinName pin1,
+ PinName pin2, PinName pin3)
+ : adc_(pin1), myAdc_(ADC1)
+ {
+ myAdc_->CR2 = ADC_CR2_ADON; // Enable ADC
+
+ ch1_ = GetChannelNumber(pin1);
+ if (pin2 != NC)
+ {
+ adc2_ = new AnalogIn(pin2);
+ ch2_ = GetChannelNumber(pin2);
+ }
+ if (pin3 != NC)
+ {
+ adc3_ = new AnalogIn(pin3);
+ ch3_ = GetChannelNumber(pin3);
+ }
+ Select1stChannel();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/InternalADC.hpp Mon Mar 16 23:59:49 2015 +0000
@@ -0,0 +1,109 @@
+//--------------------------------------------------------------
+// Class for Internal ADC using Ticker for trigger -- Header
+//
+// 2015/02/23, Copyright (c) 2015 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef INTERNAL_ADC_HPP
+#define INTERNAL_ADC_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class InternalADC
+ {
+ private:
+ // Following object of AnalogIn class will be
+ // initialized by menber initializer
+ AnalogIn adc_;
+ // Following two objects of AnalogIn class will be
+ // initailized by regular executable statements
+ AnalogIn* adc2_;
+ AnalogIn* adc3_;
+
+ Ticker timer_;
+
+ // Channel of ADC1
+ uint8_t ch1_, ch2_, ch3_;
+
+ // Exctract channel number
+ uint8_t GetChannelNumber(PinName pin)
+ {
+ uint8_t ch = 0;
+ if ((pin & 0x30) == 0x00) ch = pin;
+ if ((pin & 0x30) == 0x10) ch = (pin & 0x01) + 8;
+ if ((pin & 0x30) == 0x20) ch = (pin & 0x07) + 10;
+ return ch;
+ }
+
+ // for inhibition of copy constructor
+ InternalADC(const InternalADC&);
+ // for inhibition of substitute operator
+ InternalADC& operator=(const InternalADC&);
+
+ protected:
+ // for normalize
+ static const float AMP_ = 1.0f/2048.0f;
+
+ ADC_TypeDef* const myAdc_;
+
+ // Wait until completion of AD conversion
+ void WaitDone()
+ { while((myAdc_->SR & ADC_SR_EOC) == RESET); }
+
+ public:
+
+ // Constructor
+ // pin1: Pin Name for input as A0, A1, etc.
+ // pin2: If use 2nd channel set this parameter
+ // pin3: If use 3rd channel set this parameter
+ InternalADC(PinName pin1, PinName pin2 = NC, PinName pin3 = NC);
+
+ // Set sampling period, specifiying the period in micro-seconds
+ void SetSamplingPeriod(int us)
+ { timer_.attach_us(this, &InternalADC::SoftStart, us); }
+
+ // Read ADC with waiting, range: [0, 0x0FFF]
+ virtual uint16_t Read_u16()
+ {
+ WaitDone();
+ return myAdc_->DR;
+ }
+
+ // Read ADC with waiting, range: [-1.0f, 1.0f]
+ virtual float Read()
+ {
+ WaitDone();
+ return AMP_*((int16_t)myAdc_->DR - 2048);
+ }
+
+ // Select channel
+ void Select1stChannel() { myAdc_->SQR3 = ch1_; }
+ void Select2ndChannel()
+ {
+ if (adc2_ == NULL)
+ {
+ fprintf(stderr, "\r\n2nd channel is not assigned to any pin.\r\n");
+ return;
+ }
+ myAdc_->SQR3 = ch2_;
+ }
+ void Select3rdChannel()
+ {
+ if (adc3_ == NULL)
+ {
+ fprintf(stderr, "\r\n3rd channel is not assigned to any pin.\r\n");
+ return;
+ }
+ myAdc_->SQR3 = ch3_;
+ }
+
+ // Software start
+ void SoftStart()
+ { myAdc_->CR2 |= ADC_CR2_SWSTART; }
+
+ uint32_t ReadSQR3() { return myAdc_->SQR3; }
+ };
+}
+#endif // INTERNAL_ADC_HPP
--- a/tim4_slaveSelect.hpp Sat Mar 14 06:49:49 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-//------------------------------------------------------
-// Class for generate SPI slave select using TIM4
-//
-// Default pin assignments: PB_6 (D10)
-// PB_7, PB_8 (D15), and PB_9 (D14) also can be used
-// 2014/12/21, Copyright (c) 2014 MIKAMI, Naoki
-//------------------------------------------------------
-
-#ifndef TIM4_SLAVESELECT_HPP
-#define TIM4_SLAVESELECT_HPP
-
-#include "mbed.h"
-
-namespace Mikami
-{
- class Tim4_ss
- {
- public:
- Tim4_ss(uint16_t psc, // prescaler
- uint16_t arr = 18, // auto-reload register
- PinName pin = PB_6) // pin name
- : myTim_(TIM4)
- {
- PwmOut css(pin);
- myTim_->CR1 |= TIM_CR1_OPM; // one-pulse mode
- myTim_->PSC = psc; // prescaler
- myTim_->ARR = arr; // pulse width
- if (pin == PB_6) myTim_->CCR1 = 1;
- if (pin == PB_7) myTim_->CCR2 = 1;
- if (pin == PB_8) myTim_->CCR3 = 1;
- if (pin == PB_9) myTim_->CCR4 = 1;
- if ( (pin != PB_6) && (pin != PB_7)
- &&(pin != PB_8) && (pin != PB_9) )
- {
- fprintf(stderr, "\r\nIllegal pin name in Tim4_ss class\r\n");
- while (true) {}
- }
- }
- // Generate slave select
- void SlaveSelect()
- {
- myTim_->CNT = 0; // Set counter 0
- myTim_->CR1 |= TIM_CR1_CEN; // Enable TIM4
- __NOP();
- __NOP();
- __NOP();
- __NOP();
-#ifdef __STM32F411xE_H
- __NOP();
- __NOP();
-#endif // __STM32F411xE_H
- }
- private:
- TIM_TypeDef* myTim_;
-
- // Forbid to use copy constructor
- Tim4_ss(const Tim4_ss&);
- // Forbid to use substitution operator
- Tim4_ss operator=(const Tim4_ss&);
- };
-}
-#endif // TIM4_SLAVESELECT_HPP