Merging pull request #63 Improvements to STM32F1 I2C, CAN, RCC, and USB (f107)
Merge remote-tracking branch 'icd/master'
This commit is contained in:
commit
c904c3ae57
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
/**@}*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
144
lib/stm32/i2c.c
144
lib/stm32/i2c.c
|
@ -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;
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue