Merging pull request #63 Improvements to STM32F1 I2C, CAN, RCC, and USB (f107)

Merge remote-tracking branch 'icd/master'
This commit is contained in:
Piotr Esden-Tempski 2013-01-06 17:52:43 -08:00
commit c904c3ae57
20 changed files with 496 additions and 42 deletions

View File

@ -135,7 +135,9 @@ void can_setup(void)
CAN_BTR_SJW_1TQ,
CAN_BTR_TS1_3TQ,
CAN_BTR_TS2_4TQ,
12)) /* BRP+1: Baud rate prescaler */
12, /* BRP+1: Baud rate prescaler */
false, /* loopback mode */
false)) /* silent mode */
{
gpio_set(GPIOA, GPIO8); /* LED0 off */
gpio_set(GPIOB, GPIO4); /* LED1 off */

View File

@ -249,6 +249,8 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer));
usbd_register_control_callback(

View File

@ -439,6 +439,7 @@ LGPL License Terms @ref lgpl_license
#define CAN_BTR_SJW_3TQ (0x2 << 24)
#define CAN_BTR_SJW_4TQ (0x3 << 24)
#define CAN_BTR_SJW_MASK (0x3 << 24)
#define CAN_BTR_SJW_SHIFT 24
/* 23 Reserved, forced by hardware to 0 */
@ -452,6 +453,7 @@ LGPL License Terms @ref lgpl_license
#define CAN_BTR_TS2_7TQ (0x6 << 20)
#define CAN_BTR_TS2_8TQ (0x7 << 20)
#define CAN_BTR_TS2_MASK (0x7 << 20)
#define CAN_BTR_TS2_SHIFT 20
/* TS1[3:0]: Time segment 1 */
#define CAN_BTR_TS1_1TQ (0x0 << 16)
@ -471,6 +473,7 @@ LGPL License Terms @ref lgpl_license
#define CAN_BTR_TS1_15TQ (0xE << 16)
#define CAN_BTR_TS1_16TQ (0xF << 16)
#define CAN_BTR_TS1_MASK (0xF << 16)
#define CAN_BTR_TS1_SHIFT 16
/* 15:10 Reserved, forced by hardware to 0 */
@ -641,7 +644,8 @@ BEGIN_DECLS
void can_reset(u32 canport);
int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp);
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp,
bool loopback, bool silent);
void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
u32 fr1, u32 fr2, u32 fifo, bool enable);
@ -662,7 +666,7 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
bool *rtr, u32 *fmi, u8 *length, u8 *data);
void can_fifo_release(u32 canport, u8 fifo);
bool can_available_mailbox(u32 canport);
END_DECLS
#endif

View File

@ -51,6 +51,15 @@ u16 desig_get_flash_size(void);
*/
void desig_get_unique_id(u32 result[]);
/**
* Read the full 96 bit unique identifier and return it as a
* zero-terminated string
* @param string memory region to write the result to
8 @param string_len the size of string in bytes
*/
void desig_get_unique_id_as_string(char *string,
unsigned int string_len);
END_DECLS
#endif

View File

@ -394,6 +394,7 @@ void dma_disable_channel(u32 dma, u8 channel);
void dma_set_peripheral_address(u32 dma, u8 channel, u32 address);
void dma_set_memory_address(u32 dma, u8 channel, u32 address);
void dma_set_number_of_data(u32 dma, u8 channel, u16 number);
void dma_clear_flag(u32 dma, u32 flag);
END_DECLS

View File

@ -86,7 +86,7 @@ LGPL License Terms @ref lgpl_license
#define RCC_CFGR_MCO_SYSCLK 0x4
#define RCC_CFGR_MCO_HSICLK 0x5
#define RCC_CFGR_MCO_HSECLK 0x6
#define RCC_CFGR_RMCO_PLLCLK_DIV2 0x7
#define RCC_CFGR_MCO_PLLCLK_DIV2 0x7
#define RCC_CFGR_MCO_PLL2CLK 0x8 /* (**) */
#define RCC_CFGR_MCO_PLL3CLK_DIV2 0x9 /* (**) */
#define RCC_CFGR_MCO_XT1 0xa /* (**) */
@ -448,6 +448,24 @@ LGPL License Terms @ref lgpl_license
#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL16 0xe
#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL20 0xf
/* PREDIV: PREDIV division factor */
#define RCC_CFGR2_PREDIV_NODIV 0x0
#define RCC_CFGR2_PREDIV_DIV2 0x1
#define RCC_CFGR2_PREDIV_DIV3 0x2
#define RCC_CFGR2_PREDIV_DIV4 0x3
#define RCC_CFGR2_PREDIV_DIV5 0x4
#define RCC_CFGR2_PREDIV_DIV6 0x5
#define RCC_CFGR2_PREDIV_DIV7 0x6
#define RCC_CFGR2_PREDIV_DIV8 0x7
#define RCC_CFGR2_PREDIV_DIV9 0x8
#define RCC_CFGR2_PREDIV_DIV10 0x9
#define RCC_CFGR2_PREDIV_DIV11 0xa
#define RCC_CFGR2_PREDIV_DIV12 0xb
#define RCC_CFGR2_PREDIV_DIV13 0xc
#define RCC_CFGR2_PREDIV_DIV14 0xd
#define RCC_CFGR2_PREDIV_DIV15 0xe
#define RCC_CFGR2_PREDIV_DIV16 0xf
/* PREDIV2: PREDIV2 division factor */
#define RCC_CFGR2_PREDIV2_NODIV 0x0
#define RCC_CFGR2_PREDIV2_DIV2 0x1
@ -473,7 +491,7 @@ extern u32 rcc_ppre2_frequency;
/* --- Function prototypes ------------------------------------------------- */
typedef enum {
PLL, HSE, HSI, LSE, LSI
PLL, PLL2, PLL3, HSE, HSI, LSE, LSI
} osc_t;
BEGIN_DECLS
@ -489,6 +507,7 @@ void rcc_osc_on(osc_t osc);
void rcc_osc_off(osc_t osc);
void rcc_css_enable(void);
void rcc_css_disable(void);
void rcc_set_mco(u32 mcosrc);
void rcc_osc_bypass_enable(osc_t osc);
void rcc_osc_bypass_disable(osc_t osc);
void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en);
@ -497,6 +516,7 @@ void rcc_peripheral_reset(volatile u32 *reg, u32 reset);
void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset);
void rcc_set_sysclk_source(u32 clk);
void rcc_set_pll_multiplication_factor(u32 mul);
void rcc_set_pll2_multiplication_factor(u32 mul);
void rcc_set_pll_source(u32 pllsrc);
void rcc_set_pllxtpre(u32 pllxtpre);
void rcc_set_adcpre(u32 adcpre);
@ -512,6 +532,7 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void);
void rcc_clock_setup_in_hse_8mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_12mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_16mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void);
void rcc_backupdomain_reset(void);
END_DECLS

View File

@ -321,7 +321,14 @@ LGPL License Terms @ref lgpl_license
#define I2C_CCR_FS (1 << 15)
/* DUTY: Fast Mode Duty Cycle */
/** @defgroup i2c_duty_cycle I2C peripheral clock duty cycles
@ingroup i2c_defines
@{*/
#define I2C_CCR_DUTY (1 << 14)
#define I2C_CCR_DUTY_DIV2 0
#define I2C_CCR_DUTY_16_DIV_9 1
/**@}*/
/* Note: Bits [13:12] are reserved, and forced to 0 by hardware. */
@ -359,6 +366,7 @@ void i2c_peripheral_enable(u32 i2c);
void i2c_peripheral_disable(u32 i2c);
void i2c_send_start(u32 i2c);
void i2c_send_stop(u32 i2c);
void i2c_clear_stop(u32 i2c);
void i2c_set_own_7bit_slave_address(u32 i2c, u8 slave);
void i2c_set_own_10bit_slave_address(u32 i2c, u16 slave);
void i2c_set_fast_mode(u32 i2c);
@ -368,6 +376,18 @@ void i2c_set_ccr(u32 i2c, u16 freq);
void i2c_set_trise(u32 i2c, u16 trise);
void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite);
void i2c_send_data(u32 i2c, u8 data);
uint8_t i2c_get_data(u32 i2c);
void i2c_enable_interrupt(u32 i2c, u32 interrupt);
void i2c_disable_interrupt(u32 i2c, u32 interrupt);
void i2c_enable_ack(u32 i2c);
void i2c_disable_ack(u32 i2c);
void i2c_nack_next(u32 i2c);
void i2c_nack_current(u32 i2c);
void i2c_set_dutycycle(u32 i2c, u32 dutycycle);
void i2c_enable_dma(u32 i2c);
void i2c_disable_dma(u32 i2c);
void i2c_set_dma_last_transfer(u32 i2c);
void i2c_clear_dma_last_transfer(u32 i2c);
END_DECLS

View File

@ -24,6 +24,13 @@
BEGIN_DECLS
enum usbd_request_return_codes {
USBD_REQ_NOTSUPP = 0,
USBD_REQ_HANDLED = 1,
USBD_REQ_NEXT_CALLBACK = 2,
};
typedef struct _usbd_driver usbd_driver;
typedef struct _usbd_device usbd_device;
@ -40,9 +47,10 @@ extern u8 usbd_control_buffer[];
/* <usb.c> */
extern usbd_device *usbd_init(const usbd_driver *driver,
const struct usb_device_descriptor *dev,
const struct usb_config_descriptor *conf,
const char **strings);
const struct usb_device_descriptor *dev,
const struct usb_config_descriptor *conf,
const char **strings, int num_strings);
extern void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size);
extern void usbd_register_reset_callback(usbd_device *usbd_dev,

View File

@ -223,4 +223,7 @@ struct usb_iface_assoc_descriptor {
#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
sizeof(struct usb_iface_assoc_descriptor)
enum usb_language_id {
USB_LANGID_ENGLISH_US = 0x409,
};
#endif

View File

@ -85,7 +85,8 @@ Initialize the selected CAN peripheral block.
@returns int 0 on success, 1 on initialization failure.
*/
int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp)
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp,
bool loopback, bool silent)
{
u32 wait_ack = 0x00000000;
u32 can_msr_inak_timeout = 0x0000FFFF;
@ -107,6 +108,9 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)
return 1;
/* clear can timing bits */
CAN_BTR(canport) = 0;
/* Set the automatic bus-off management. */
if (ttcm)
CAN_MCR(canport) |= CAN_MCR_TTCM;
@ -138,8 +142,19 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
else
CAN_MCR(canport) &= ~CAN_MCR_TXFP;
if (silent)
CAN_BTR(canport) |= CAN_BTR_SILM;
else
CAN_BTR(canport) &= ~CAN_BTR_SILM;
if (loopback)
CAN_BTR(canport) |= CAN_BTR_LBKM;
else
CAN_BTR(canport) &= ~CAN_BTR_LBKM;
/* Set bit timings. */
CAN_BTR(canport) = sjw | ts2 | ts1 |
CAN_BTR(canport) |= sjw | ts2 | ts1 |
(u32)(CAN_BTR_BRP_MASK & (brp - 1));
/* Request initialization "leave". */
@ -456,3 +471,8 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
if (release)
can_fifo_release(canport, fifo);
}
bool can_available_mailbox(u32 canport)
{
return CAN_TSR(canport) & (CAN_TSR_TME0 | CAN_TSR_TME1 | CAN_TSR_TME2);
}

View File

@ -35,3 +35,25 @@ void desig_get_unique_id(u32 result[])
result[1] = bits63_32;
result[2] = bits31_16 << 16 | bits15_0;
}
void desig_get_unique_id_as_string(char *string,
unsigned int string_len)
{
int i, len;
u8 device_id[12];
static const char chars[] = "0123456789ABCDEF";
desig_get_unique_id((u32 *)device_id);
/* Each byte produces two characters */
len = (2 * sizeof(device_id) < string_len) ?
2 * sizeof(device_id) : string_len - 1;
for (i = 0; i < len; i += 2) {
string[i] = chars[(device_id[i / 2] >> 0) & 0x0F];
string[i + 1] = chars[(device_id[i / 2] >> 4) & 0x0F];
}
string[len] = '\0';
}

View File

@ -433,5 +433,10 @@ void dma_set_number_of_data(u32 dma, u8 channel, u16 number)
{
DMA_CNDTR(dma, channel) = number;
}
void dma_clear_flag(u32 dma, u32 flag)
{
DMA_ISR(dma) &= ~flag;
}
/**@}*/

View File

@ -164,7 +164,7 @@ value cannot be ascertained from the hardware.
*/
void gpio_primary_remap(u8 swjdisable, u32 maps)
{
AFIO_MAPR = swjdisable | (maps & 0x1FFFFF);
AFIO_MAPR |= swjdisable | (maps & 0x1FFFFF);
}
/*-----------------------------------------------------------------------------*/
@ -182,7 +182,7 @@ The AFIO remapping feature is used only with the STM32F10x series.
*/
void gpio_secondary_remap(u32 maps)
{
AFIO_MAPR2 = maps;
AFIO_MAPR2 |= maps;
}
/**@}*/

View File

@ -71,6 +71,12 @@ void rcc_osc_ready_int_clear(osc_t osc)
case PLL:
RCC_CIR |= RCC_CIR_PLLRDYC;
break;
case PLL2:
RCC_CIR |= RCC_CIR_PLL2RDYC;
break;
case PLL3:
RCC_CIR |= RCC_CIR_PLL3RDYC;
break;
case HSE:
RCC_CIR |= RCC_CIR_HSERDYC;
break;
@ -98,6 +104,12 @@ void rcc_osc_ready_int_enable(osc_t osc)
case PLL:
RCC_CIR |= RCC_CIR_PLLRDYIE;
break;
case PLL2:
RCC_CIR |= RCC_CIR_PLL2RDYIE;
break;
case PLL3:
RCC_CIR |= RCC_CIR_PLL3RDYIE;
break;
case HSE:
RCC_CIR |= RCC_CIR_HSERDYIE;
break;
@ -125,6 +137,12 @@ void rcc_osc_ready_int_disable(osc_t osc)
case PLL:
RCC_CIR &= ~RCC_CIR_PLLRDYIE;
break;
case PLL2:
RCC_CIR &= ~RCC_CIR_PLL2RDYIE;
break;
case PLL3:
RCC_CIR &= ~RCC_CIR_PLL3RDYIE;
break;
case HSE:
RCC_CIR &= ~RCC_CIR_HSERDYIE;
break;
@ -153,6 +171,12 @@ int rcc_osc_ready_int_flag(osc_t osc)
case PLL:
return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
break;
case PLL2:
return ((RCC_CIR & RCC_CIR_PLL2RDYF) != 0);
break;
case PLL3:
return ((RCC_CIR & RCC_CIR_PLL3RDYF) != 0);
break;
case HSE:
return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
break;
@ -203,6 +227,12 @@ void rcc_wait_for_osc_ready(osc_t osc)
case PLL:
while ((RCC_CR & RCC_CR_PLLRDY) == 0);
break;
case PLL2:
while ((RCC_CR & RCC_CR_PLL2RDY) == 0);
break;
case PLL3:
while ((RCC_CR & RCC_CR_PLL3RDY) == 0);
break;
case HSE:
while ((RCC_CR & RCC_CR_HSERDY) == 0);
break;
@ -238,6 +268,12 @@ void rcc_osc_on(osc_t osc)
case PLL:
RCC_CR |= RCC_CR_PLLON;
break;
case PLL2:
RCC_CR |= RCC_CR_PLL2ON;
break;
case PLL3:
RCC_CR |= RCC_CR_PLL3ON;
break;
case HSE:
RCC_CR |= RCC_CR_HSEON;
break;
@ -273,6 +309,12 @@ void rcc_osc_off(osc_t osc)
case PLL:
RCC_CR &= ~RCC_CR_PLLON;
break;
case PLL2:
RCC_CR &= ~RCC_CR_PLL2ON;
break;
case PLL3:
RCC_CR &= ~RCC_CR_PLL3ON;
break;
case HSE:
RCC_CR &= ~RCC_CR_HSEON;
break;
@ -331,6 +373,8 @@ void rcc_osc_bypass_enable(osc_t osc)
RCC_BDCR |= RCC_BDCR_LSEBYP;
break;
case PLL:
case PLL2:
case PLL3:
case HSI:
case LSI:
/* Do nothing, only HSE/LSE allowed here. */
@ -361,6 +405,8 @@ void rcc_osc_bypass_disable(osc_t osc)
RCC_BDCR &= ~RCC_BDCR_LSEBYP;
break;
case PLL:
case PLL2:
case PLL3:
case HSI:
case LSI:
/* Do nothing, only HSE/LSE allowed here. */
@ -484,6 +530,40 @@ void rcc_set_pll_multiplication_factor(u32 mul)
RCC_CFGR = (reg32 | (mul << 18));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL2 Multiplication Factor.
@note This only has effect when the PLL is disabled.
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
*/
void rcc_set_pll2_multiplication_factor(u32 mul)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
RCC_CFGR2 = (reg32 | (mul << 8));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL3 Multiplication Factor.
@note This only has effect when the PLL is disabled.
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
*/
void rcc_set_pll3_multiplication_factor(u32 mul)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~((1 << 15) | (1 << 14) | (1 << 13) | (1 << 12));
RCC_CFGR2 = (reg32 | (mul << 12));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL Clock Source.
@ -602,6 +682,36 @@ void rcc_set_usbpre(u32 usbpre)
RCC_CFGR = (reg32 | (usbpre << 22));
}
void rcc_set_prediv1(u32 prediv)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~(1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
RCC_CFGR2 |= (reg32 | prediv);
}
void rcc_set_prediv2(u32 prediv)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~(1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);
RCC_CFGR2 |= (reg32 | (prediv << 4));
}
void rcc_set_prediv1_source(u32 rccsrc)
{
RCC_CFGR2 &= ~(1 << 16);
RCC_CFGR2 |= (rccsrc << 16);
}
void rcc_set_mco(u32 mcosrc)
{
u32 reg32;
reg32 = RCC_CFGR;
reg32 &= ~((1 << 27) | (1 << 26) | (1 << 25) | (1 << 24));
RCC_CFGR |= (reg32 | (mcosrc << 24));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Get the System Clock Source.
@ -1030,6 +1140,63 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 72MHz from HSE at 25MHz
*/
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void)
{
/* Enable external high-speed oscillator 25MHz. */
rcc_osc_on(HSE);
rcc_wait_for_osc_ready(HSE);
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);
/*
* Sysclk runs with 72MHz -> 2 waitstates.
* 0WS from 0-24MHz
* 1WS from 24-48MHz
* 2WS from 48-72MHz
*/
flash_set_ws(FLASH_LATENCY_2WS);
/*
* Set prescalers for AHB, ADC, ABP1, ABP2.
* Do this before touching the PLL (TODO: why?).
*/
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */
/* Set pll2 prediv and multiplier */
rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5);
rcc_set_pll2_multiplication_factor(RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8);
/* Enable PLL2 oscillator and wait for it to stabilize */
rcc_osc_on(PLL2);
rcc_wait_for_osc_ready(PLL2);
/* Set pll1 prediv/multiplier, prediv1 src, and usb predivider */
rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK);
rcc_set_prediv1_source(RCC_CFGR2_PREDIV1SRC_PLL2_CLK);
rcc_set_prediv1(RCC_CFGR2_PREDIV_DIV5);
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9);
rcc_set_pll_source(RCC_CFGR_PLLSRC_PREDIV1_CLK);
rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3);
/* enable PLL1 and wait for it to stabilize */
rcc_osc_on(PLL);
rcc_wait_for_osc_ready(PLL);
/* Select PLL as SYSCLK source. */
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
/* Set the peripheral clock frequencies used */
rcc_ppre1_frequency = 36000000;
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Reset the backup domain

View File

@ -67,6 +67,8 @@ void rtc_awake_from_off(osc_t clock_source)
RCC_BDCR |= (1 << 9) | (1 << 8);
break;
case PLL:
case PLL2:
case PLL3:
case HSI:
/* Unusable clock source, here to prevent warnings. */
/* Turn off clock sources to RTC. */

View File

@ -124,6 +124,18 @@ void i2c_send_stop(u32 i2c)
I2C_CR1(i2c) |= I2C_CR1_STOP;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Clear Stop Flag.
Clear the "Send Stop" flag in the I2C config register
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_clear_stop(u32 i2c)
{
I2C_CR1(i2c) &= ~I2C_CR1_STOP;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set the 7 bit Slave Address for the Peripheral.
@ -269,5 +281,135 @@ void i2c_send_data(u32 i2c, u8 data)
I2C_DR(i2c) = data;
}
/**@}*/
/*-----------------------------------------------------------------------------*/
/** @brief I2C Get Data.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
uint8_t i2c_get_data(u32 i2c)
{
return I2C_DR(i2c) & 0xff;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Enable Interrupt
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] interrupt Unsigned int32. Interrupt to enable.
*/
void i2c_enable_interrupt(u32 i2c, u32 interrupt)
{
I2C_CR2(i2c) |= interrupt;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Disable Interrupt
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] interrupt Unsigned int32. Interrupt to disable.
*/
void i2c_disable_interrupt(u32 i2c, u32 interrupt)
{
I2C_CR2(i2c) &= ~interrupt;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Enable ACK
Enables acking of own 7/10 bit address
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_enable_ack(u32 i2c)
{
I2C_CR1(i2c) |= I2C_CR1_ACK;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Disable ACK
Disables acking of own 7/10 bit address
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_disable_ack(u32 i2c)
{
I2C_CR1(i2c) &= ~I2C_CR1_ACK;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C NACK Next Byte
Causes the I2C controller to NACK the reception of the next byte
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_nack_next(u32 i2c)
{
I2C_CR1(i2c) |= I2C_CR1_POS;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C NACK Next Byte
Causes the I2C controller to NACK the reception of the current byte
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_nack_current(u32 i2c)
{
I2C_CR1(i2c) &= ~I2C_CR1_POS;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set clock duty cycle
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] dutycycle Unsigned int32. I2C duty cycle @ref i2c_duty_cycle.
*/
void i2c_set_dutycycle(u32 i2c, u32 dutycycle)
{
if (dutycycle == I2C_CCR_DUTY_DIV2)
I2C_CCR(i2c) &= ~I2C_CCR_DUTY;
else
I2C_CCR(i2c) |= I2C_CCR_DUTY;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Enable DMA
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_enable_dma(u32 i2c)
{
I2C_CR2(i2c) |= I2C_CR2_DMAEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Disable DMA
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_disable_dma(u32 i2c)
{
I2C_CR2(i2c) &= ~I2C_CR2_DMAEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set DMA last transfer
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_set_dma_last_transfer(u32 i2c)
{
I2C_CR2(i2c) |= I2C_CR2_LAST;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Clear DMA last transfer
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_clear_dma_last_transfer(u32 i2c)
{
I2C_CR2(i2c) &= ~I2C_CR2_LAST;
}
/**@}*/

View File

@ -44,7 +44,7 @@ u8 usbd_control_buffer[128] __attribute__((weak));
usbd_device *usbd_init(const usbd_driver *driver,
const struct usb_device_descriptor *dev,
const struct usb_config_descriptor *conf,
const char **strings)
const char **strings, int num_strings)
{
usbd_device *usbd_dev;
@ -54,6 +54,7 @@ usbd_device *usbd_init(const usbd_driver *driver,
usbd_dev->desc = dev;
usbd_dev->config = conf;
usbd_dev->strings = strings;
usbd_dev->num_strings = num_strings;
usbd_dev->ctrl_buf = usbd_control_buffer;
usbd_dev->ctrl_buf_len = sizeof(usbd_control_buffer);

View File

@ -99,11 +99,12 @@ static int usb_control_request_dispatch(usbd_device *usbd_dev,
&(usbd_dev->control_state.ctrl_buf),
&(usbd_dev->control_state.ctrl_len),
&(usbd_dev->control_state.complete));
if (result)
if (result == USBD_REQ_HANDLED ||
result == USBD_REQ_NOTSUPP)
return result;
}
}
/* Try standard request if not already handled. */
return _usbd_standard_request(usbd_dev, req,
&(usbd_dev->control_state.ctrl_buf),

View File

@ -29,6 +29,7 @@ struct _usbd_device {
const struct usb_device_descriptor *desc;
const struct usb_config_descriptor *config;
const char **strings;
int num_strings;
u8 *ctrl_buf; /**< Internal buffer used for control transfers */
u16 ctrl_buf_len;

View File

@ -90,52 +90,75 @@ static u16 build_config_descriptor(usbd_device *usbd_dev,
return total;
}
static int usb_descriptor_type(u16 wValue)
{
return wValue >> 8;
}
static int usb_descriptor_index(u16 wValue)
{
return wValue & 0xFF;
}
static int usb_standard_get_descriptor(usbd_device *usbd_dev,
struct usb_setup_data *req,
u8 **buf, u16 *len)
{
int i;
int i, array_idx, descr_idx;
struct usb_string_descriptor *sd;
switch (req->wValue >> 8) {
descr_idx = usb_descriptor_index(req->wValue);
switch (usb_descriptor_type(req->wValue)) {
case USB_DT_DEVICE:
*buf = (u8 *) usbd_dev->desc;
*len = MIN(*len, usbd_dev->desc->bLength);
return 1;
return USBD_REQ_HANDLED;
case USB_DT_CONFIGURATION:
*buf = usbd_dev->ctrl_buf;
*len = build_config_descriptor(usbd_dev, req->wValue & 0xff,
*buf, *len);
return 1;
*len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len);
return USBD_REQ_HANDLED;
case USB_DT_STRING:
sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf;
if (!usbd_dev->strings)
return 0; /* Device doesn't support strings. */
if (descr_idx == 0) {
/* Send sane Language ID descriptor... */
sd->wData[0] = USB_LANGID_ENGLISH_US;
sd->bLength = sizeof(sd->bLength) + sizeof(sd->bDescriptorType)
+ sizeof(sd->wData[0]);
/* Check that string index is in range. */
for (i = 0; i <= (req->wValue & 0xff); i++)
if (usbd_dev->strings[i] == NULL)
return 0;
*len = MIN(*len, sd->bLength);
} else {
array_idx = descr_idx - 1;
if (!usbd_dev->strings)
return USBD_REQ_NOTSUPP; /* Device doesn't support strings. */
/* Check that string index is in range. */
if (array_idx >= usbd_dev->num_strings)
return USBD_REQ_NOTSUPP;
/* Strings with Language ID differnet from
* USB_LANGID_ENGLISH_US are not supported */
if (req->wIndex != USB_LANGID_ENGLISH_US)
return USBD_REQ_NOTSUPP;
/* Ths string is returned as UTF16, hence the multiplication */
sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 +
sizeof(sd->bLength) + sizeof(sd->bDescriptorType);
*len = MIN(*len, sd->bLength);
for (i = 0; i < (*len / 2) - 1; i++)
sd->wData[i] =
usbd_dev->strings[array_idx][i];
}
sd->bLength = strlen(usbd_dev->strings[req->wValue & 0xff])
* 2 + 2;
sd->bDescriptorType = USB_DT_STRING;
*buf = (u8 *)sd;
*len = MIN(*len, sd->bLength);
for (i = 0; i < (*len / 2) - 1; i++)
sd->wData[i] =
usbd_dev->strings[req->wValue & 0xff][i];
/* Send sane Language ID descriptor... */
if ((req->wValue & 0xff) == 0)
sd->wData[0] = 0x409;
return 1;
return USBD_REQ_HANDLED;
}
return 0;
return USBD_REQ_NOTSUPP;
}
static int usb_standard_set_address(usbd_device *usbd_dev,