Merge pull request #377 from dinau/disco_f303vc_update

[DISCO-F303VC] Updated with F302R8 recent changes
pull/379/head
Martin Kojtal 2014-06-26 10:18:14 +01:00
commit 9fec469ec6
15 changed files with 208 additions and 88 deletions

View File

@ -141,7 +141,7 @@
* @{ * @{
*/ */
uint32_t SystemCoreClock = 72000000; /* Default with HSI. Will be updated if HSE is used */ uint32_t SystemCoreClock = 64000000; /* Default with HSI. Will be updated if HSE is used */
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
@ -153,8 +153,6 @@ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}
* @{ * @{
*/ */
void SetSysClock(void);
#if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0) #if (USE_PLL_HSE_XTAL != 0) || (USE_PLL_HSE_EXTC != 0)
uint8_t SetSysClock_PLL_HSE(uint8_t bypass); uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
#endif #endif
@ -208,9 +206,6 @@ void SystemInit(void)
/* Disable all interrupts */ /* Disable all interrupts */
RCC->CIR = 0x00000000; RCC->CIR = 0x00000000;
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings */
SetSysClock();
/* Configure the Vector Table location add offset address ------------------*/ /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM #ifdef VECT_TAB_SRAM
@ -218,6 +213,9 @@ void SystemInit(void)
#else #else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif #endif
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings */
SetSysClock();
} }
/** /**
@ -344,7 +342,7 @@ void SetSysClock(void)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_Init(GPIOA, &GPIO_InitStructure);
// Select the clock to output // Select the clock to output
RCC_MCOConfig(RCC_MCOSource_SYSCLK); RCC_MCOConfig(RCC_MCOSource_SYSCLK, RCC_MCOPrescaler_1);
*/ */
} }

View File

@ -65,6 +65,7 @@ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Cloc
extern void SystemInit(void); extern void SystemInit(void);
extern void SystemCoreClockUpdate(void); extern void SystemCoreClockUpdate(void);
extern void SetSysClock(void);
/** /**
* @} * @}

View File

@ -25,15 +25,15 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "mbed_assert.h"
#include "analogout_api.h" #include "analogout_api.h"
#if DEVICE_ANALOGOUT #if DEVICE_ANALOGOUT
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h"
#define RANGE_12BIT (0xFFF) #define DAC_RANGE (0xFFF) // 12 bits
static const PinMap PinMap_DAC[] = { static const PinMap PinMap_DAC[] = {
{PA_4, DAC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // DAC_OUT1 {PA_4, DAC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // DAC_OUT1
@ -47,10 +47,7 @@ void analogout_init(dac_t *obj, PinName pin) {
// Get the peripheral name (DAC_1, ...) from the pin and assign it to the object // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT(obj->dac != (DACName)NC);
if (obj->dac == (DACName)NC) {
error("DAC pin mapping failed");
}
dac = (DAC_TypeDef *)(obj->dac); dac = (DAC_TypeDef *)(obj->dac);
@ -79,6 +76,12 @@ void analogout_init(dac_t *obj, PinName pin) {
} }
void analogout_free(dac_t *obj) { void analogout_free(dac_t *obj) {
DAC_TypeDef *dac = (DAC_TypeDef *)(obj->dac);
// Disable DAC
DAC_DeInit(dac);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, DISABLE);
// Configure GPIO
pin_function(obj->channel, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
} }
static inline void dac_write(dac_t *obj, uint16_t value) { static inline void dac_write(dac_t *obj, uint16_t value) {
@ -106,24 +109,23 @@ void analogout_write(dac_t *obj, float value) {
if (value < 0.0f) { if (value < 0.0f) {
dac_write(obj, 0); // Min value dac_write(obj, 0); // Min value
} else if (value > 1.0f) { } else if (value > 1.0f) {
dac_write(obj, (uint16_t)RANGE_12BIT); // Max value dac_write(obj, (uint16_t)DAC_RANGE); // Max value
} else { } else {
dac_write(obj, (uint16_t)(value * (float)RANGE_12BIT)); dac_write(obj, (uint16_t)(value * (float)DAC_RANGE));
} }
} }
void analogout_write_u16(dac_t *obj, uint16_t value) { void analogout_write_u16(dac_t *obj, uint16_t value) {
if (value > (uint16_t)RANGE_12BIT) { if (value > (uint16_t)DAC_RANGE) {
dac_write(obj, (uint16_t)RANGE_12BIT); // Max value dac_write(obj, (uint16_t)DAC_RANGE); // Max value
} } else {
else {
dac_write(obj, value); dac_write(obj, value);
} }
} }
float analogout_read(dac_t *obj) { float analogout_read(dac_t *obj) {
uint32_t value = dac_read(obj); uint32_t value = dac_read(obj);
return (float)value * (1.0f / (float)RANGE_12BIT); return (float)((float)value * (1.0f / (float)DAC_RANGE));
} }
uint16_t analogout_read_u16(dac_t *obj) { uint16_t analogout_read_u16(dac_t *obj) {

View File

@ -42,7 +42,7 @@
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0 // Not yet supported #define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1 #define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0 // Not yet supported #define DEVICE_SPISLAVE 0 // Not yet supported

View File

@ -154,7 +154,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_index = 6; irq_index = 6;
break; break;
default: default:
error("This pin is not supported with InterruptIn.\n"); error("This pin is not supported with InterruptIn.");
return -1; return -1;
} }

View File

@ -34,6 +34,7 @@
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h"
/* Timeout values for flags and events waiting loops. These timeouts are /* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will not based on accurate values, they just guarantee that the application will
@ -73,6 +74,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Enable I2C clock // Enable I2C clock
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
@ -95,10 +97,9 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
} }
void i2c_frequency(i2c_t *obj, int hz) { void i2c_frequency(i2c_t *obj, int hz) {
MBED_ASSERT((hz == 100000) || (hz == 200000) || (hz == 400000) || (hz == 1000000));
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure; I2C_InitTypeDef I2C_InitStructure;
uint32_t tim; uint32_t tim = 0;
// Disable the Fast Mode Plus capability // Disable the Fast Mode Plus capability
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock
@ -111,24 +112,25 @@ void i2c_frequency(i2c_t *obj, int hz) {
* Fast Mode (up to 400 kHz) * Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz) * Fast Mode Plus (up to 1 MHz)
Below values obtained with: Below values obtained with:
- I2C clock source = 8 MHz (HSI clock per default) - I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE)
- Analog filter delay = ON - Analog filter delay = ON
- Digital filter coefficient = 0 - Digital filter coefficient = 0
- Rise time = 100 ns - Rise time = 100 ns
- Fall time = 10ns - Fall time = 10ns
*/ */
if (SystemCoreClock == 64000000) {
switch (hz) { switch (hz) {
case 100000: case 100000:
tim = 0x00201D2B; // Standard mode tim = 0x60302730; // Standard mode
break; break;
case 200000: case 200000:
tim = 0x0010021E; // Fast Mode tim = 0x00C07AB3; // Fast Mode
break; break;
case 400000: case 400000:
tim = 0x0010020A; // Fast Mode tim = 0x00C0216C; // Fast Mode
break; break;
case 1000000: case 1000000:
tim = 0x00100001; // Fast Mode Plus tim = 0x00900B22; // Fast Mode Plus
// Enable the Fast Mode Plus capability // Enable the Fast Mode Plus capability
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE); SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE);
@ -138,8 +140,37 @@ void i2c_frequency(i2c_t *obj, int hz) {
} }
break; break;
default: default:
error("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported.");
break; break;
} }
} else if (SystemCoreClock == 72000000) {
switch (hz) {
case 100000:
tim = 0x10C08DCF; // Standard mode
break;
case 200000:
tim = 0xA010031A; // Fast Mode
break;
case 400000:
tim = 0x00E0257A; // Fast Mode
break;
case 1000000:
tim = 0x00A00D26; // Fast Mode Plus
// Enable the Fast Mode Plus capability
if (obj->i2c == I2C_1) {
SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE);
}
if (obj->i2c == I2C_2) {
SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, ENABLE);
}
break;
default:
error("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported.");
break;
}
} else {
error("System clock setting is not supported.");
}
// I2C configuration // I2C configuration
I2C_DeInit(i2c); I2C_DeInit(i2c);
@ -184,12 +215,13 @@ inline int i2c_stop(i2c_t *obj) {
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int count; int count;
int timeout;
int value; int value;
if (length == 0) return 0; if (length == 0) return 0;
// Configure slave address, nbytes, reload, end mode and start or stop generation // Configure slave address, nbytes, reload, end mode and start or stop generation
I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
// Read all bytes // Read all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
@ -197,48 +229,39 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
data[count] = (char)value; data[count] = (char)value;
} }
timeout = FLAG_TIMEOUT;
while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) {
timeout--;
if (timeout == 0) return 0;
}
if (stop) i2c_stop(obj);
return length; return length;
} }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
//int timeout; int timeout;
int count; int count;
if (length == 0) return 0; if (length == 0) return 0;
// [TODO] The stop is always sent even with I2C_SoftEnd_Mode. To be corrected. // Configure slave address, nbytes, reload, end mode and start generation
I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
// Configure slave address, nbytes, reload, end mode and start or stop generation
//if (stop) {
I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
//}
//else {
// I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//}
// Write all bytes // Write all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
if (i2c_byte_write(obj, data[count]) != 1) { i2c_byte_write(obj, data[count]);
i2c_stop(obj);
return 0;
}
} }
/* timeout = FLAG_TIMEOUT;
if (stop) { while (!I2C_GetFlagStatus(i2c, I2C_FLAG_TC)) {
// Wait until STOPF flag is set
timeout = LONG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_ISR_STOPF) == RESET) {
timeout--; timeout--;
if (timeout == 0) { if (timeout == 0) return 0;
return 0;
}
} }
// Clear STOPF flag
I2C_ClearFlag(i2c, I2C_ICR_STOPCF); if (stop) i2c_stop(obj);
}
*/
return count; return count;
} }
@ -301,6 +324,9 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg; uint16_t tmpreg;
// reset own address enable
i2c->OAR1 &= ~ I2C_OAR1_OA1EN;
// Get the old register value // Get the old register value
tmpreg = i2c->OAR1; tmpreg = i2c->OAR1;
// Reset address bits // Reset address bits
@ -308,7 +334,7 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
// Set new address // Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value // Store the new register value
i2c->OAR1 = tmpreg; i2c->OAR1 = tmpreg | I2C_OAR1_OA1EN;
} }
void i2c_slave_mode(i2c_t *obj, int enable_slave) { void i2c_slave_mode(i2c_t *obj, int enable_slave) {
@ -322,8 +348,20 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) { int i2c_slave_receive(i2c_t *obj) {
// TO BE DONE I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
return (0); int event = NoData;
if (I2C_GetFlagStatus(i2c, I2C_ISR_BUSY) == SET) {
if (I2C_GetFlagStatus(i2c, I2C_ISR_ADDR) == SET) {
// Check direction
if (I2C_GetFlagStatus(i2c, I2C_ISR_DIR) == SET) {
event = ReadAddressed;
} else event = WriteAddressed;
// Clear adress match flag to generate an acknowledge
i2c->ICR |= I2C_ICR_ADDRCF;
}
}
return event;
} }
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {

View File

@ -25,8 +25,7 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "cmsis.h"
extern void SystemCoreClockUpdate(void);
// This function is called after RAM initialization and before main. // This function is called after RAM initialization and before main.
void mbed_sdk_init() { void mbed_sdk_init() {

View File

@ -70,6 +70,8 @@ struct serial_s {
uint32_t databits; uint32_t databits;
uint32_t stopbits; uint32_t stopbits;
uint32_t parity; uint32_t parity;
PinName pin_tx;
PinName pin_rx;
}; };
struct spi_s { struct spi_s {
@ -80,6 +82,10 @@ struct spi_s {
uint32_t mode; uint32_t mode;
uint32_t nss; uint32_t nss;
uint32_t br_presc; uint32_t br_presc;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
}; };
struct i2c_s { struct i2c_s {

View File

@ -28,8 +28,8 @@
******************************************************************************* *******************************************************************************
*/ */
#include "mbed_assert.h" #include "mbed_assert.h"
#include "device.h"
#include "pinmap.h" #include "pinmap.h"
#include "PortNames.h"
#include "error.h" #include "error.h"
// Enable GPIO clock and return GPIO base address // Enable GPIO clock and return GPIO base address

View File

@ -28,12 +28,13 @@
******************************************************************************* *******************************************************************************
*/ */
#include "port_api.h" #include "port_api.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
#include "pinmap.h" #include "pinmap.h"
#include "gpio_api.h" #include "gpio_api.h"
#include "error.h" #include "error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)

View File

@ -27,11 +27,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************* *******************************************************************************
*/ */
#include "mbed_assert.h"
#include "pwmout_api.h" #include "pwmout_api.h"
#if DEVICE_PWMOUT
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h"
// TIM2 cannot be used because already used by the us_ticker // TIM2 cannot be used because already used by the us_ticker
static const PinMap PinMap_PWM[] = { static const PinMap PinMap_PWM[] = {
@ -272,3 +274,5 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
float value = (float)us / (float)obj->period; float value = (float)us / (float)obj->period;
pwmout_write(obj, value); pwmout_write(obj, value);
} }
#endif

View File

@ -29,42 +29,77 @@
*/ */
#include "rtc_api.h" #include "rtc_api.h"
#if DEVICE_RTC
#include "wait_api.h"
#define LSE_STARTUP_TIMEOUT ((uint16_t)500) // delay in ms
static int rtc_inited = 0; static int rtc_inited = 0;
void rtc_init(void) { void rtc_init(void) {
uint32_t StartUpCounter = 0;
uint32_t LSEStatus = 0;
uint32_t rtc_freq = 0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock
PWR_BackupAccessCmd(ENABLE); // Enable access to RTC PWR_BackupAccessCmd(ENABLE); // Enable access to Backup domain
// Be sure to start correctly // Reset back up registers
RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE); RCC_BackupResetCmd(DISABLE);
// Note: the LSI is used as RTC source clock // Enable LSE clock
RCC_LSEConfig(RCC_LSE_ON);
// Wait till LSE is ready
do {
LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY);
wait_ms(1);
StartUpCounter++;
} while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT));
if (StartUpCounter > LSE_STARTUP_TIMEOUT) {
// The LSE has not started, use LSI instead.
// The RTC Clock may vary due to LSI frequency dispersion. // The RTC Clock may vary due to LSI frequency dispersion.
RCC_LSEConfig(RCC_LSE_OFF);
RCC_LSICmd(ENABLE); // Enable LSI RCC_LSICmd(ENABLE); // Enable LSI
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture
} else {
// The LSE has correctly started
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source
rtc_freq = LSE_VALUE;
}
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
RTC_WaitForSynchro(); // Wait for RTC registers synchronization RTC_WaitForSynchro(); // Wait for RTC registers synchronization
uint32_t lsi_freq = 40000; // [TODO] To be measured precisely using a timer input capture
RTC_InitTypeDef RTC_InitStructure; RTC_InitTypeDef RTC_InitStructure;
RTC_InitStructure.RTC_AsynchPrediv = 127; RTC_InitStructure.RTC_AsynchPrediv = 127;
RTC_InitStructure.RTC_SynchPrediv = (lsi_freq / 128) - 1; RTC_InitStructure.RTC_SynchPrediv = (rtc_freq / 128) - 1;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure); RTC_Init(&RTC_InitStructure);
PWR_BackupAccessCmd(DISABLE); // Disable access to Backup domain
rtc_inited = 1; rtc_inited = 1;
} }
void rtc_free(void) { void rtc_free(void) {
RCC_DeInit(); // Resets the RCC clock configuration to the default reset state // Reset RTC
PWR_BackupAccessCmd(ENABLE); // Enable access to Backup Domain
RTC_DeInit();
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
// Disable RTC, LSE and LSI clocks
RCC_RTCCLKCmd(DISABLE);
RCC_LSEConfig(RCC_LSE_OFF);
RCC_LSICmd(DISABLE);
rtc_inited = 0; rtc_inited = 0;
} }
@ -136,3 +171,5 @@ void rtc_write(time_t t) {
RTC_SetTime(RTC_Format_BIN, &timeStruct); RTC_SetTime(RTC_Format_BIN, &timeStruct);
PWR_BackupAccessCmd(DISABLE); // Disable access to RTC PWR_BackupAccessCmd(DISABLE); // Disable access to RTC
} }
#endif

View File

@ -29,6 +29,9 @@
*/ */
#include "mbed_assert.h" #include "mbed_assert.h"
#include "serial_api.h" #include "serial_api.h"
#if DEVICE_SERIAL
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include <string.h> #include <string.h>
@ -97,12 +100,15 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Enable USART clock // Enable USART clock
if (obj->uart == UART_1) { if (obj->uart == UART_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
obj->index = 0;
} }
if (obj->uart == UART_2) { if (obj->uart == UART_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
obj->index = 1;
} }
if (obj->uart == UART_3) { if (obj->uart == UART_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
obj->index = 2;
} }
// Configure the UART pins // Configure the UART pins
@ -117,12 +123,10 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
obj->stopbits = USART_StopBits_1; obj->stopbits = USART_StopBits_1;
obj->parity = USART_Parity_No; obj->parity = USART_Parity_No;
init_usart(obj); obj->pin_tx = tx;
obj->pin_rx = rx;
// The index is used by irq init_usart(obj);
if (obj->uart == UART_1) obj->index = 0;
if (obj->uart == UART_2) obj->index = 1;
if (obj->uart == UART_3) obj->index = 2;
// For stdio management // For stdio management
if (obj->uart == STDIO_UART) { if (obj->uart == STDIO_UART) {
@ -133,6 +137,27 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
} }
void serial_free(serial_t *obj) { void serial_free(serial_t *obj) {
// Reset UART and disable clock
if (obj->uart == UART_1) {
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);
}
if (obj->uart == UART_2) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, DISABLE);
}
if (obj->uart == UART_3) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, DISABLE);
}
// Configure GPIOs
pin_function(obj->pin_tx, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
pin_function(obj->pin_rx, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
serial_irq_ids[obj->index] = 0; serial_irq_ids[obj->index] = 0;
} }
@ -306,3 +331,5 @@ void serial_break_clear(serial_t *obj) {
USART_RequestCmd(usart, USART_Request_SBKRQ, DISABLE); USART_RequestCmd(usart, USART_Request_SBKRQ, DISABLE);
USART_ClearFlag(usart, USART_FLAG_SBK); USART_ClearFlag(usart, USART_FLAG_SBK);
} }
#endif

View File

@ -28,10 +28,10 @@
******************************************************************************* *******************************************************************************
*/ */
#include "sleep_api.h" #include "sleep_api.h"
#include "cmsis.h"
// This function is in the system_stm32f30x.c file #if DEVICE_SLEEP
extern void SetSysClock(void);
#include "cmsis.h"
// MCU SLEEP mode // MCU SLEEP mode
void sleep(void) { void sleep(void) {
@ -53,3 +53,5 @@ void deepsleep(void) {
// After wake-up from STOP reconfigure the PLL // After wake-up from STOP reconfigure the PLL
SetSysClock(); SetSysClock();
} }
#endif

View File

@ -122,13 +122,18 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
obj->br_presc = SPI_BaudRatePrescaler_256; obj->br_presc = SPI_BaudRatePrescaler_256;
obj->pin_miso = miso;
obj->pin_mosi = mosi;
obj->pin_sclk = sclk;
obj->pin_ssel = ssel;
if (ssel == NC) { // Master if (ssel == NC) { // Master
obj->mode = SPI_Mode_Master; obj->mode = SPI_Mode_Master;
obj->nss = SPI_NSS_Soft; obj->nss = SPI_NSS_Soft;
} else { // Slave } else { // Slave
pinmap_pinout(ssel, PinMap_SPI_SSEL); pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->mode = SPI_Mode_Slave; obj->mode = SPI_Mode_Slave;
obj->nss = SPI_NSS_Soft; obj->nss = SPI_NSS_Hard;
} }
init_spi(obj); init_spi(obj);
@ -141,10 +146,10 @@ void spi_free(spi_t *obj) {
void spi_format(spi_t *obj, int bits, int mode, int slave) { void spi_format(spi_t *obj, int bits, int mode, int slave) {
// Save new values // Save new values
if (bits == 8) { if (bits == 16) {
obj->bits = SPI_DataSize_8b;
} else {
obj->bits = SPI_DataSize_16b; obj->bits = SPI_DataSize_16b;
} else {
obj->bits = SPI_DataSize_8b;
} }
switch (mode) { switch (mode) {
@ -248,7 +253,7 @@ int spi_master_write(spi_t *obj, int value) {
} }
int spi_slave_receive(spi_t *obj) { int spi_slave_receive(spi_t *obj) {
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0);
}; };
int spi_slave_read(spi_t *obj) { int spi_slave_read(spi_t *obj) {