[DISCO_F303VC] reorg hal part II

pull/1004/head
ohagendorf 2015-03-23 01:01:30 +01:00
parent 8176b7c773
commit 5e01a14bf1
9 changed files with 58 additions and 1467 deletions

View File

@ -1,123 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* 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.
*/
#include "mbed_assert.h"
#include "analogout_api.h"
#if DEVICE_ANALOGOUT
#include "cmsis.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
#define DAC_RANGE (0xFFF) // 12 bits
static DAC_HandleTypeDef DacHandle;
void analogout_init(dac_t *obj, PinName pin)
{
DAC_ChannelConfTypeDef sConfig;
// Get the peripheral name from the pin and assign it to the object
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
MBED_ASSERT(obj->dac != (DACName)NC);
// Configure GPIO
pinmap_pinout(pin, PinMap_DAC);
// Save the pin for future use
obj->pin = pin;
// Enable DAC clock
__DAC1_CLK_ENABLE();
// Configure DAC
DacHandle.Instance = (DAC_TypeDef *)(obj->dac);
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1);
analogout_write_u16(obj, 0);
}
void analogout_free(dac_t *obj)
{
// Reset DAC and disable clock
__DAC1_FORCE_RESET();
__DAC1_RELEASE_RESET();
__DAC1_CLK_DISABLE();
// Configure GPIO
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
static inline void dac_write(dac_t *obj, uint16_t value)
{
HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
}
static inline int dac_read(dac_t *obj)
{
return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
}
void analogout_write(dac_t *obj, float value)
{
if (value < 0.0f) {
dac_write(obj, 0); // Min value
} else if (value > 1.0f) {
dac_write(obj, (uint16_t)DAC_RANGE); // Max value
} else {
dac_write(obj, (uint16_t)(value * (float)DAC_RANGE));
}
}
void analogout_write_u16(dac_t *obj, uint16_t value)
{
if (value > (uint16_t)DAC_RANGE) {
dac_write(obj, (uint16_t)DAC_RANGE); // Max value
} else {
dac_write(obj, value);
}
}
float analogout_read(dac_t *obj)
{
uint32_t value = dac_read(obj);
return (float)((float)value * (1.0f / (float)DAC_RANGE));
}
uint16_t analogout_read_u16(dac_t *obj)
{
return (uint16_t)dac_read(obj);
}
#endif // DEVICE_ANALOGOUT

View File

@ -1,262 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* 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.
*******************************************************************************
*/
#include <stddef.h>
#include "cmsis.h"
#include "gpio_irq_api.h"
#include "pinmap.h"
#include "mbed_error.h"
#define EDGE_NONE (0)
#define EDGE_RISE (1)
#define EDGE_FALL (2)
#define EDGE_BOTH (3)
#define CHANNEL_NUM (7)
static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0};
static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0};
static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0, 0, 0, 0, 0};
static gpio_irq_handler irq_handler;
static void handle_interrupt_in(uint32_t irq_index)
{
// Retrieve the gpio and pin that generate the irq
GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]);
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
// Clear interrupt flag
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
}
if (channel_ids[irq_index] == 0) return;
// Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) {
irq_handler(channel_ids[irq_index], IRQ_FALL);
} else {
irq_handler(channel_ids[irq_index], IRQ_RISE);
}
}
// The irq_index is passed to the function
// EXTI line 0
static void gpio_irq0(void)
{
handle_interrupt_in(0);
}
// EXTI line 1
static void gpio_irq1(void)
{
handle_interrupt_in(1);
}
// EXTI line 2
static void gpio_irq2(void)
{
handle_interrupt_in(2);
}
// EXTI line 3
static void gpio_irq3(void)
{
handle_interrupt_in(3);
}
// EXTI line 4
static void gpio_irq4(void)
{
handle_interrupt_in(4);
}
// EXTI lines 5 to 9
static void gpio_irq5(void)
{
handle_interrupt_in(5);
}
// EXTI lines 10 to 15
static void gpio_irq6(void)
{
handle_interrupt_in(6);
}
extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
uint32_t irq_index;
if (pin == NC) return -1;
uint32_t port_index = STM_PORT(pin);
uint32_t pin_index = STM_PIN(pin);
// Select irq number and interrupt routine
switch (pin_index) {
case 0:
irq_n = EXTI0_IRQn;
vector = (uint32_t)&gpio_irq0;
irq_index = 0;
break;
case 1:
irq_n = EXTI1_IRQn;
vector = (uint32_t)&gpio_irq1;
irq_index = 1;
break;
case 2:
irq_n = EXTI2_TSC_IRQn;
vector = (uint32_t)&gpio_irq2;
irq_index = 2;
break;
case 3:
irq_n = EXTI3_IRQn;
vector = (uint32_t)&gpio_irq3;
irq_index = 3;
break;
case 4:
irq_n = EXTI4_IRQn;
vector = (uint32_t)&gpio_irq4;
irq_index = 4;
break;
case 5:
case 6:
case 7:
case 8:
case 9:
irq_n = EXTI9_5_IRQn;
vector = (uint32_t)&gpio_irq5;
irq_index = 5;
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
irq_n = EXTI15_10_IRQn;
vector = (uint32_t)&gpio_irq6;
irq_index = 6;
break;
default:
error("InterruptIn error: pin not supported.\n");
return -1;
}
// Enable GPIO clock
uint32_t gpio_add = Set_GPIO_Clock(port_index);
// Configure GPIO
pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0));
// Enable EXTI interrupt
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
// Save informations for future use
obj->irq_n = irq_n;
obj->irq_index = irq_index;
obj->event = EDGE_NONE;
obj->pin = pin;
channel_ids[irq_index] = id;
channel_gpio[irq_index] = gpio_add;
channel_pin[irq_index] = pin_index;
irq_handler = handler;
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
channel_ids[obj->irq_index] = 0;
channel_gpio[obj->irq_index] = 0;
channel_pin[obj->irq_index] = 0;
// Disable EXTI line
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
obj->event = EDGE_NONE;
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
uint32_t mode = STM_MODE_IT_EVT_RESET;
uint32_t pull = GPIO_NOPULL;
if (enable) {
if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
} else { // NONE or RISE
mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE;
}
}
if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
} else { // NONE or FALL
mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL;
}
}
} else { // Disable
if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL;
} else { // NONE or RISE
mode = STM_MODE_IT_EVT_RESET;
obj->event = EDGE_NONE;
}
}
if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE;
} else { // NONE or FALL
mode = STM_MODE_IT_EVT_RESET;
obj->event = EDGE_NONE;
}
}
}
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
}
void gpio_irq_enable(gpio_irq_t *obj)
{
NVIC_EnableIRQ(obj->irq_n);
}
void gpio_irq_disable(gpio_irq_t *obj)
{
NVIC_DisableIRQ(obj->irq_n);
obj->event = EDGE_NONE;
}

View File

@ -1,428 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* 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.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "i2c_api.h"
#if DEVICE_I2C
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x4000)
#define LONG_TIMEOUT ((int)0x8000)
I2C_HandleTypeDef I2cHandle;
int i2c1_inited = 0;
int i2c2_inited = 0;
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
// Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
MBED_ASSERT(obj->i2c != (I2CName)NC);
// Enable I2C clock and pinout if not done
if ((obj->i2c == I2C_1) && !i2c1_inited) {
i2c1_inited = 1;
__HAL_RCC_I2C1_CONFIG(RCC_I2C1CLKSOURCE_SYSCLK);
__I2C1_CLK_ENABLE();
// Configure I2C1 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
if ((obj->i2c == I2C_2) && !i2c2_inited) {
i2c2_inited = 1;
__I2C2_CLK_ENABLE();
// Configure I2C2 pins
pinmap_pinout(sda, PinMap_I2C_SDA);
pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain);
}
// Reset to clear pending flags if any
i2c_reset(obj);
// I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default
}
void i2c_frequency(i2c_t *obj, int hz)
{
uint32_t tim = 0;
MBED_ASSERT((hz == 100000) || (hz == 400000) || (hz == 1000000));
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
// wait before init
timeout = LONG_TIMEOUT;
while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
/*
Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235)
* Standard mode (up to 100 kHz)
* Fast Mode (up to 400 kHz)
* Fast Mode Plus (up to 1 MHz)
Below values obtained with:
- I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE)
- Analog filter delay = ON
- Digital filter coefficient = 0
*/
if (SystemCoreClock == 64000000) {
switch (hz) {
case 100000:
tim = 0x10B17DB4; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00E22163; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00A00D1E; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
} else if (SystemCoreClock == 72000000) {
switch (hz) {
case 100000:
tim = 0x10D28DCB; // Standard mode with Rise time = 120ns, Fall time = 120ns
break;
case 400000:
tim = 0x00F32571; // Fast Mode with Rise time = 120ns, Fall time = 120ns
break;
case 1000000:
tim = 0x00C00D24; // Fast Mode Plus with Rise time = 120ns, Fall time = 10ns
break;
default:
break;
}
}
// Enable the Fast Mode Plus capability
if (hz == 1000000) {
if (obj->i2c == I2C_1) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C1);
}
if (obj->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2);
}
}
// I2C configuration
I2cHandle.Init.Timing = tim;
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2cHandle.Init.OwnAddress1 = 0;
I2cHandle.Init.OwnAddress2 = 0;
I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
HAL_I2C_Init(&I2cHandle);
}
inline int i2c_start(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Generate the START condition
i2c->CR2 |= I2C_CR2_START;
// Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == RESET) {
if ((timeout--) == 0) {
return 1;
}
}
return 0;
}
inline int i2c_stop(i2c_t *obj)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition
i2c->CR2 |= I2C_CR2_STOP;
return 0;
}
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
int value;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_READ);
// Read all bytes
for (count = 0; count < length; count++) {
value = i2c_byte_read(obj, 0);
data[count] = (char)value;
}
// Wait transfer complete
timeout = LONG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return length;
}
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int timeout;
int count;
/* update CR2 register */
i2c->CR2 = (i2c->CR2 & (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP)))
| (uint32_t)(((uint32_t)address & I2C_CR2_SADD) | (((uint32_t)length << 16) & I2C_CR2_NBYTES) | (uint32_t)I2C_SOFTEND_MODE | (uint32_t)I2C_GENERATE_START_WRITE);
for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]);
}
// Wait transfer complete
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TC) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_TC);
// If not repeated start, send stop.
if (stop) {
i2c_stop(obj);
/* Wait until STOPF flag is set */
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
timeout--;
if (timeout == 0) {
return -1;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_STOPF);
}
return count;
}
int i2c_byte_read(i2c_t *obj, int last)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the byte is received
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c->RXDR;
}
int i2c_byte_write(i2c_t *obj, int data)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout;
// Wait until the previous byte is transmitted
timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXIS) == RESET) {
if ((timeout--) == 0) {
return 0;
}
}
i2c->TXDR = (uint8_t)data;
return 1;
}
void i2c_reset(i2c_t *obj)
{
int timeout;
// wait before reset
timeout = LONG_TIMEOUT;
while((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
}
#if DEVICE_I2CSLAVE
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// disable
i2c->OAR1 &= (uint32_t)(~I2C_OAR1_OA1EN);
// Get the old register value
tmpreg = i2c->OAR1;
// Reset address bits
tmpreg &= 0xFC00;
// Set new address
tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
// Store the new register value
i2c->OAR1 = tmpreg;
// enable
i2c->OAR1 |= I2C_OAR1_OA1EN;
}
void i2c_slave_mode(i2c_t *obj, int enable_slave)
{
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg;
// Get the old register value
tmpreg = i2c->OAR1;
// Enable / disable slave
if (enable_slave == 1) {
tmpreg |= I2C_OAR1_OA1EN;
} else {
tmpreg &= (uint32_t)(~I2C_OAR1_OA1EN);
}
// Set new mode
i2c->OAR1 = tmpreg;
}
// See I2CSlave.h
#define NoData 0 // the slave has not been addressed
#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
#define WriteGeneral 2 // the master is writing to all slave
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj)
{
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
int retValue = NoData;
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_DIR) == 1)
retValue = ReadAddressed;
else
retValue = WriteAddressed;
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
}
}
return (retValue);
}
int i2c_slave_read(i2c_t *obj, char *data, int length)
{
char size = 0;
while (size < length) data[size++] = (char)i2c_byte_read(obj, 0);
return size;
}
int i2c_slave_write(i2c_t *obj, const char *data, int length)
{
char size = 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
do {
i2c_byte_write(obj, data[size]);
size++;
} while (size < length);
return size;
}
#endif // DEVICE_I2CSLAVE
#endif // DEVICE_I2C

View File

@ -1,352 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* 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.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "serial_api.h"
#if DEVICE_SERIAL
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include <string.h>
#define UART_NUM (3)
static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0};
static uart_irq_handler irq_handler;
UART_HandleTypeDef UartHandle;
int stdio_uart_inited = 0;
serial_t stdio_uart;
static void init_uart(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
UartHandle.Init.BaudRate = obj->baudrate;
UartHandle.Init.WordLength = obj->databits;
UartHandle.Init.StopBits = obj->stopbits;
UartHandle.Init.Parity = obj->parity;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
if (obj->pin_rx == NC) {
UartHandle.Init.Mode = UART_MODE_TX;
} else if (obj->pin_tx == NC) {
UartHandle.Init.Mode = UART_MODE_RX;
} else {
UartHandle.Init.Mode = UART_MODE_TX_RX;
}
// Disable the reception overrun detection
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT;
UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
HAL_UART_Init(&UartHandle);
}
void serial_init(serial_t *obj, PinName tx, PinName rx)
{
// Determine the UART to use (UART_1, UART_2, ...)
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
MBED_ASSERT(obj->uart != (UARTName)NC);
// Enable USART clock + switch to SystemClock
if (obj->uart == UART_1) {
__USART1_CLK_ENABLE();
__HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK);
obj->index = 0;
}
if (obj->uart == UART_2) {
__USART2_CLK_ENABLE();
__HAL_RCC_USART2_CONFIG(RCC_USART2CLKSOURCE_SYSCLK);
obj->index = 1;
}
if (obj->uart == UART_3) {
__USART3_CLK_ENABLE();
__HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK);
obj->index = 2;
}
// Configure the UART pins
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
if (tx != NC) {
pin_mode(tx, PullUp);
}
if (rx != NC) {
pin_mode(rx, PullUp);
}
// Configure UART
obj->baudrate = 9600;
obj->databits = UART_WORDLENGTH_8B;
obj->stopbits = UART_STOPBITS_1;
obj->parity = UART_PARITY_NONE;
obj->pin_tx = tx;
obj->pin_rx = rx;
init_uart(obj);
// For stdio management
if (obj->uart == STDIO_UART) {
stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t));
}
}
void serial_free(serial_t *obj)
{
// Reset UART and disable clock
if (obj->uart == UART_1) {
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__USART1_CLK_DISABLE();
}
if (obj->uart == UART_2) {
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__USART2_CLK_DISABLE();
}
if (obj->uart == UART_3) {
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__USART3_CLK_DISABLE();
}
// Configure GPIOs
pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_rx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
serial_irq_ids[obj->index] = 0;
}
void serial_baud(serial_t *obj, int baudrate)
{
obj->baudrate = baudrate;
init_uart(obj);
}
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
if (data_bits == 9) {
obj->databits = UART_WORDLENGTH_9B;
} else {
obj->databits = UART_WORDLENGTH_8B;
}
switch (parity) {
case ParityOdd:
case ParityForced0:
obj->parity = UART_PARITY_ODD;
break;
case ParityEven:
case ParityForced1:
obj->parity = UART_PARITY_EVEN;
break;
default: // ParityNone
obj->parity = UART_PARITY_NONE;
break;
}
if (stop_bits == 2) {
obj->stopbits = UART_STOPBITS_2;
} else {
obj->stopbits = UART_STOPBITS_1;
}
init_uart(obj);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
static void uart_irq(UARTName name, int id)
{
UartHandle.Instance = (USART_TypeDef *)name;
if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq);
__HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
}
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = UartHandle.Instance->RDR; // Clear RXNE bit
}
}
}
static void uart1_irq(void)
{
uart_irq(UART_1, 0);
}
static void uart2_irq(void)
{
uart_irq(UART_2, 1);
}
static void uart3_irq(void)
{
uart_irq(UART_3, 2);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{
irq_handler = handler;
serial_irq_ids[obj->index] = id;
}
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0;
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
if (obj->uart == UART_1) {
irq_n = USART1_IRQn;
vector = (uint32_t)&uart1_irq;
}
if (obj->uart == UART_2) {
irq_n = USART2_IRQn;
vector = (uint32_t)&uart2_irq;
}
if (obj->uart == UART_3) {
irq_n = USART3_IRQn;
vector = (uint32_t)&uart3_irq;
}
if (enable) {
if (irq == RxIrq) {
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
} else { // TxIrq
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
}
NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n);
} else { // disable
int all_disabled = 0;
if (irq == RxIrq) {
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
// Check if TxIrq is disabled too
if ((UartHandle.Instance->CR1 & USART_CR1_TCIE) == 0) all_disabled = 1;
} else { // TxIrq
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
// Check if RxIrq is disabled too
if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
}
if (all_disabled) NVIC_DisableIRQ(irq_n);
}
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
int serial_getc(serial_t *obj)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_readable(obj));
if (obj->databits == UART_WORDLENGTH_8B) {
return (int)(uart->RDR & (uint8_t)0xFF);
} else {
return (int)(uart->RDR & (uint16_t)0x1FF);
}
}
void serial_putc(serial_t *obj, int c)
{
USART_TypeDef *uart = (USART_TypeDef *)(obj->uart);
while (!serial_writable(obj));
if (obj->databits == UART_WORDLENGTH_8B) {
uart->TDR = (uint8_t)(c & (uint8_t)0xFF);
} else {
uart->TDR = (uint16_t)(c & (uint16_t)0x1FF);
}
}
int serial_readable(serial_t *obj)
{
int status;
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is received
status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) ? 1 : 0);
return status;
}
int serial_writable(serial_t *obj)
{
int status;
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
// Check if data is transmitted
status = ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TXE) != RESET) ? 1 : 0);
return status;
}
void serial_clear(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
__HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_TC);
__HAL_UART_SEND_REQ(&UartHandle, UART_RXDATA_FLUSH_REQUEST);
}
void serial_pinout_tx(PinName tx)
{
pinmap_pinout(tx, PinMap_UART_TX);
}
void serial_break_set(serial_t *obj)
{
UartHandle.Instance = (USART_TypeDef *)(obj->uart);
HAL_LIN_SendBreak(&UartHandle);
}
void serial_break_clear(serial_t *obj)
{
}
#endif

View File

@ -1,297 +0,0 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* 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.
*******************************************************************************
*/
#include "mbed_assert.h"
#include "spi_api.h"
#if DEVICE_SPI
#include <math.h>
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
static SPI_HandleTypeDef SpiHandle;
static void init_spi(spi_t *obj)
{
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
__HAL_SPI_DISABLE(&SpiHandle);
SpiHandle.Init.Mode = obj->mode;
SpiHandle.Init.BaudRatePrescaler = obj->br_presc;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.CLKPhase = obj->cpha;
SpiHandle.Init.CLKPolarity = obj->cpol;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.DataSize = obj->bits;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.NSS = obj->nss;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
HAL_SPI_Init(&SpiHandle);
__HAL_SPI_ENABLE(&SpiHandle);
}
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
// Determine the SPI to use
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
MBED_ASSERT(obj->spi != (SPIName)NC);
// Enable SPI clock
if (obj->spi == SPI_2) {
__SPI2_CLK_ENABLE();
}
if (obj->spi == SPI_3) {
__SPI3_CLK_ENABLE();
}
// Configure the SPI pins
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
// Save new values
obj->bits = SPI_DATASIZE_8BIT;
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE;
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz (HSI) or 1.13 MHz (HSE)
obj->pin_miso = miso;
obj->pin_mosi = mosi;
obj->pin_sclk = sclk;
obj->pin_ssel = ssel;
if (ssel == NC) { // SW NSS Master mode
obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT;
} else { // Slave
pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT;
}
init_spi(obj);
}
void spi_free(spi_t *obj)
{
// Reset SPI and disable clock
if (obj->spi == SPI_2) {
__SPI2_FORCE_RESET();
__SPI2_RELEASE_RESET();
__SPI2_CLK_DISABLE();
}
if (obj->spi == SPI_3) {
__SPI3_FORCE_RESET();
__SPI3_RELEASE_RESET();
__SPI3_CLK_DISABLE();
}
// Configure GPIOs
pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_mosi, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_sclk, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin_ssel, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
void spi_format(spi_t *obj, int bits, int mode, int slave)
{
// Save new values
if (bits == 16) {
obj->bits = SPI_DATASIZE_16BIT;
} else {
obj->bits = SPI_DATASIZE_8BIT;
}
switch (mode) {
case 0:
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE;
break;
case 1:
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_2EDGE;
break;
case 2:
obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_1EDGE;
break;
default:
obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_2EDGE;
break;
}
if (slave == 0) {
obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT;
} else {
obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT;
}
init_spi(obj);
}
void spi_frequency(spi_t *obj, int hz)
{
// Values depend of APB1CLK : 32 MHz if HSI is used, 36 MHz if HSE is used
if (hz < 250000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 125 kHz - 141 kHz
} else if ((hz >= 250000) && (hz < 500000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 250 kHz - 280 kHz
} else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 500 kHz - 560 kHz
} else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz - 1.13 MHz
} else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 2 MHz - 2.25 MHz
} else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 4 MHz - 4.5 MHz
} else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 8 MHz - 9 MHz
} else { // >= 16000000
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
}
init_spi(obj);
}
static inline int ssp_readable(spi_t *obj)
{
int status;
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is received
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
return status;
}
static inline int ssp_writeable(spi_t *obj)
{
int status;
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is transmitted
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) != RESET) ? 1 : 0);
return status;
}
static inline void ssp_write(spi_t *obj, int value)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj));
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
*p_spi_dr = (uint8_t)value;
} else { // SPI_DATASIZE_16BIT
spi->DR = (uint16_t)value;
}
}
static inline int ssp_read(spi_t *obj)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj));
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
return (int)(*p_spi_dr);
} else {
return (int)spi->DR;
}
}
static inline int ssp_busy(spi_t *obj)
{
int status;
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_BSY) != RESET) ? 1 : 0);
return status;
}
int spi_master_write(spi_t *obj, int value)
{
ssp_write(obj, value);
return ssp_read(obj);
}
int spi_slave_receive(spi_t *obj)
{
return ((ssp_readable(obj) && !ssp_busy(obj)) ? 1 : 0);
};
int spi_slave_read(spi_t *obj)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj));
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
return (int)(*p_spi_dr);
} else {
return (int)spi->DR;
}
}
void spi_slave_write(spi_t *obj, int value)
{
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj));
if (obj->bits == SPI_DATASIZE_8BIT) {
// Force 8-bit access to the data register
uint8_t *p_spi_dr = 0;
p_spi_dr = (uint8_t *) & (spi->DR);
*p_spi_dr = (uint8_t)value;
} else { // SPI_DATASIZE_16BIT
spi->DR = (uint16_t)value;
}
}
int spi_busy(spi_t *obj)
{
return ssp_busy(obj);
}
#endif

View File

@ -50,8 +50,8 @@ typedef enum {
UART_1 = (int)USART1_BASE, UART_1 = (int)USART1_BASE,
UART_2 = (int)USART2_BASE, UART_2 = (int)USART2_BASE,
UART_3 = (int)USART3_BASE, UART_3 = (int)USART3_BASE,
UART_4 = (int)USART3_BASE, UART_4 = (int)UART4_BASE,
UART_5 = (int)USART3_BASE UART_5 = (int)UART5_BASE
} UARTName; } UARTName;
#define STDIO_UART_TX PA_2 #define STDIO_UART_TX PA_2

View File

@ -79,6 +79,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
pin_mode(scl, OpenDrain); pin_mode(scl, OpenDrain);
} }
#if defined(I2C3_BASE)
if ((obj->i2c == I2C_3) && !i2c3_inited) { if ((obj->i2c == I2C_3) && !i2c3_inited) {
i2c3_inited = 1; i2c3_inited = 1;
__I2C3_CLK_ENABLE(); __I2C3_CLK_ENABLE();
@ -88,6 +89,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
pin_mode(sda, OpenDrain); pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain); pin_mode(scl, OpenDrain);
} }
#endif
// Reset to clear pending flags if any // Reset to clear pending flags if any
i2c_reset(obj); i2c_reset(obj);
@ -160,9 +162,11 @@ void i2c_frequency(i2c_t *obj, int hz)
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2); __HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C2);
} }
#if defined(I2C3_BASE)
if (obj->i2c == I2C_3) { if (obj->i2c == I2C_3) {
__HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C3); __HAL_SYSCFG_FASTMODEPLUS_ENABLE(HAL_SYSCFG_FASTMODEPLUS_I2C3);
} }
#endif
} }
// I2C configuration // I2C configuration

View File

@ -37,9 +37,9 @@
#include <string.h> #include <string.h>
#include "PeripheralPins.h" #include "PeripheralPins.h"
#define UART_NUM (3) #define UART_NUM (5)
static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0}; static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0, 0, 0};
static uart_irq_handler irq_handler; static uart_irq_handler irq_handler;
@ -99,16 +99,20 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
__HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK); __HAL_RCC_USART3_CONFIG(RCC_USART3CLKSOURCE_SYSCLK);
obj->index = 2; obj->index = 2;
} }
#if defined(UART4_BASE)
if (obj->uart == UART_4) { if (obj->uart == UART_4) {
__UART4_CLK_ENABLE(); __UART4_CLK_ENABLE();
__HAL_RCC_UART4_CONFIG(RCC_UART4CLKSOURCE_SYSCLK); __HAL_RCC_UART4_CONFIG(RCC_UART4CLKSOURCE_SYSCLK);
obj->index = 3; obj->index = 3;
} }
#endif
#if defined(UART5_BASE)
if (obj->uart == UART_5) { if (obj->uart == UART_5) {
__UART5_CLK_ENABLE(); __UART5_CLK_ENABLE();
__HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_SYSCLK); __HAL_RCC_UART5_CONFIG(RCC_UART5CLKSOURCE_SYSCLK);
obj->index = 4; obj->index = 4;
} }
#endif
// Configure the UART pins // Configure the UART pins
pinmap_pinout(tx, PinMap_UART_TX); pinmap_pinout(tx, PinMap_UART_TX);
@ -156,16 +160,20 @@ void serial_free(serial_t *obj)
__USART3_RELEASE_RESET(); __USART3_RELEASE_RESET();
__USART3_CLK_DISABLE(); __USART3_CLK_DISABLE();
} }
#if defined(UART4_BASE)
if (obj->uart == UART_4) { if (obj->uart == UART_4) {
__UART4_FORCE_RESET(); __UART4_FORCE_RESET();
__UART4_RELEASE_RESET(); __UART4_RELEASE_RESET();
__UART4_CLK_DISABLE(); __UART4_CLK_DISABLE();
} }
#endif
#if defined(UART5_BASE)
if (obj->uart == UART_5) { if (obj->uart == UART_5) {
__UART5_FORCE_RESET(); __UART5_FORCE_RESET();
__UART5_RELEASE_RESET(); __UART5_RELEASE_RESET();
__UART5_CLK_DISABLE(); __UART5_CLK_DISABLE();
} }
#endif
// Configure GPIOs // Configure GPIOs
pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(obj->pin_tx, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
@ -245,15 +253,19 @@ static void uart3_irq(void)
uart_irq(UART_3, 2); uart_irq(UART_3, 2);
} }
#if defined(UART4_BASE)
static void uart4_irq(void) static void uart4_irq(void)
{ {
uart_irq(UART_4, 3); uart_irq(UART_4, 3);
} }
#endif
#if defined(UART5_BASE)
static void uart5_irq(void) static void uart5_irq(void)
{ {
uart_irq(UART_5, 4); uart_irq(UART_5, 4);
} }
#endif
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
{ {
@ -283,15 +295,19 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
vector = (uint32_t)&uart3_irq; vector = (uint32_t)&uart3_irq;
} }
#if defined(UART4_BASE)
if (obj->uart == UART_4) { if (obj->uart == UART_4) {
irq_n = UART4_IRQn; irq_n = UART4_IRQn;
vector = (uint32_t)&uart4_irq; vector = (uint32_t)&uart4_irq;
} }
#endif
#if defined(UART5_BASE)
if (obj->uart == UART_5) { if (obj->uart == UART_5) {
irq_n = UART5_IRQn; irq_n = UART5_IRQn;
vector = (uint32_t)&uart5_irq; vector = (uint32_t)&uart5_irq;
} }
#endif
if (enable) { if (enable) {

View File

@ -81,13 +81,17 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
__SPI1_CLK_ENABLE(); __SPI1_CLK_ENABLE();
} }
#if defined(SPI2_BASE)
if (obj->spi == SPI_2) { if (obj->spi == SPI_2) {
__SPI2_CLK_ENABLE(); __SPI2_CLK_ENABLE();
} }
#endif
#if defined(SPI3_BASE)
if (obj->spi == SPI_3) { if (obj->spi == SPI_3) {
__SPI3_CLK_ENABLE(); __SPI3_CLK_ENABLE();
} }
#endif
// Configure the SPI pins // Configure the SPI pins
pinmap_pinout(mosi, PinMap_SPI_MOSI); pinmap_pinout(mosi, PinMap_SPI_MOSI);
@ -98,7 +102,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
obj->bits = SPI_DATASIZE_8BIT; obj->bits = SPI_DATASIZE_8BIT;
obj->cpol = SPI_POLARITY_LOW; obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE; obj->cpha = SPI_PHASE_1EDGE;
obj->br_presc = SPI_BAUDRATEPRESCALER_32; #if defined(TARGET_STM32F334C8)
obj->br_presc = SPI_BAUDRATEPRESCALER_256;
#else
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 1 MHz (HSI) or 1.13 MHz (HSE)
#endif
obj->pin_miso = miso; obj->pin_miso = miso;
obj->pin_mosi = mosi; obj->pin_mosi = mosi;
@ -126,17 +134,21 @@ void spi_free(spi_t *obj)
__SPI1_CLK_DISABLE(); __SPI1_CLK_DISABLE();
} }
#if defined(SPI2_BASE)
if (obj->spi == SPI_2) { if (obj->spi == SPI_2) {
__SPI2_FORCE_RESET(); __SPI2_FORCE_RESET();
__SPI2_RELEASE_RESET(); __SPI2_RELEASE_RESET();
__SPI2_CLK_DISABLE(); __SPI2_CLK_DISABLE();
} }
#endif
#if defined(SPI3_BASE)
if (obj->spi == SPI_3) { if (obj->spi == SPI_3) {
__SPI3_FORCE_RESET(); __SPI3_FORCE_RESET();
__SPI3_RELEASE_RESET(); __SPI3_RELEASE_RESET();
__SPI3_CLK_DISABLE(); __SPI3_CLK_DISABLE();
} }
#endif
// Configure GPIOs // Configure GPIOs
pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(obj->pin_miso, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
@ -186,6 +198,26 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
void spi_frequency(spi_t *obj, int hz) void spi_frequency(spi_t *obj, int hz)
{ {
#if defined(TARGET_STM32F334C8)
// Values depend of APB2CLK : 64 MHz if HSI is used, 72 MHz if HSE is used
if (hz < 500000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 250 kHz - 281 kHz
} else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 500 kHz - 563 kHz
} else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1 MHz - 1.13 MHz
} else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2 MHz - 2.25 MHz
} else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 4 MHz - 4.5 MHz
} else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 8 MHz - 9 MHz
} else if ((hz >= 16000000) && (hz < 32000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 16 MHz - 18 MHz
} else { // >= 32000000
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 32 MHz - 36 MHz
}
#else
// Values depend of APB1CLK and APB2CLK : 32 MHz if HSI is used, 36 MHz if HSE is used // Values depend of APB1CLK and APB2CLK : 32 MHz if HSI is used, 36 MHz if HSE is used
if (obj->spi == SPI_1) { if (obj->spi == SPI_1) {
if (hz < 500000) { if (hz < 500000) {
@ -224,6 +256,7 @@ void spi_frequency(spi_t *obj, int hz)
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 16 MHz - 18 MHz
} }
} }
#endif
init_spi(obj); init_spi(obj);
} }