Skip to content

Commit 75877cb

Browse files
committed
AT32F415: Run at 144MHz
1 parent c7a3c76 commit 75877cb

File tree

9 files changed

+100
-32
lines changed

9 files changed

+100
-32
lines changed

inc/decls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "mcu/common.h"
2121
#if MCU == STM32F105
2222
#include "mcu/stm32f105_regs.h"
23+
#include "mcu/at32f415_regs.h"
2324
#include "mcu/stm32f105.h"
2425
#elif MCU == AT32F435
2526
#include "mcu/at32f435_regs.h"

inc/mcu/at32f415_regs.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* at32f415_regs.h
3+
*
4+
* Extra registers and features of the AT32F415 that we use, over and above
5+
* the baseline features of the STM32F105.
6+
*
7+
* Written & released by Keir Fraser <[email protected]>
8+
*
9+
* This is free and unencumbered software released into the public domain.
10+
* See the file COPYING for more details, or visit <http://unlicense.org>.
11+
*/
12+
13+
#define RCC_CFGR_PLLMUL_18 ((uint32_t)0x20040000)
14+
#define RCC_CFGR_USBPSC_3 ((uint32_t)0x08400000)
15+
16+
#define RCC_PLL (&rcc->cfgr2)
17+
#define RCC_PLL_PLLCFGEN (1u<<31)
18+
#define RCC_PLL_FREF_MASK (7u<<24)
19+
#define RCC_PLL_FREF_8M (2u<<24)
20+
21+
static volatile uint32_t * const RCC_MISC2 = (uint32_t *)(RCC_BASE + 0x54);
22+
#define RCC_MISC2_AUTOSTEP_EN (3u<< 4)
23+
24+
#define TIM_CR1_PMEN (1u<<10)
25+
26+
/*
27+
* Local variables:
28+
* mode: C
29+
* c-file-style: "Linux"
30+
* c-basic-offset: 4
31+
* tab-width: 4
32+
* indent-tabs-mode: nil
33+
* End:
34+
*/

inc/mcu/at32f435.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ static USB_OTG usb_otg = (struct usb_otg *)USB_OTG_BASE;
5656

5757
/* Clocks */
5858
#define SYSCLK_MHZ 288
59-
#define AHB_MHZ (SYSCLK_MHZ / 1) /* 288MHz */
60-
#define APB1_MHZ (SYSCLK_MHZ / 2) /* 144MHz */
61-
#define APB2_MHZ (SYSCLK_MHZ / 2) /* 144MHz */
59+
#define AHB_MHZ 288
60+
#define APB1_MHZ 144
61+
#define APB2_MHZ 144
6262

6363
/* GPIO */
6464
void gpio_set_af(GPIO gpio, unsigned int pin, unsigned int af);

inc/mcu/stm32f105.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ static USART usart3 = (struct usart *)USART3_BASE;
5050
static USB_OTG usb_otg = (struct usb_otg *)USB_OTG_BASE;
5151

5252
/* Clocks */
53-
#define SYSCLK_MHZ 72
54-
#define AHB_MHZ (SYSCLK_MHZ / 1) /* 72MHz */
55-
#define APB1_MHZ (SYSCLK_MHZ / 2) /* 36MHz */
56-
#define APB2_MHZ (SYSCLK_MHZ / 1) /* 72MHz */
53+
extern unsigned int sysclk_mhz;
54+
extern unsigned int apb1_mhz;
55+
#define SYSCLK_MHZ sysclk_mhz
56+
#define AHB_MHZ sysclk_mhz
57+
#define APB1_MHZ apb1_mhz
58+
#define APB2_MHZ 72
5759

5860
#define SOFTIRQ_0 43
5961
#define SOFTIRQ_1 44

inc/mcu/stm32f105_regs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ struct rcc {
8989
#define RCC_CFGR_PLLSRC_HSI (0u<<16)
9090
#define RCC_CFGR_PLLSRC_PREDIV1 (1u<<16)
9191
#define RCC_CFGR_ADCPRE_DIV8 (3u<<14)
92-
#define RCC_CFGR_PPRE1_DIV2 (4u<<8)
92+
#define RCC_CFGR_APB2PSC_2 (4u<<11)
93+
#define RCC_CFGR_APB1PSC_2 (4u<< 8)
9394
#define RCC_CFGR_SWS_HSI (0u<<2)
9495
#define RCC_CFGR_SWS_HSE (1u<<2)
9596
#define RCC_CFGR_SWS_PLL (2u<<2)

src/console.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
#define usart_gpio gpioa
2121
#define usart_tx_pin 9
2222
#define usart_rx_pin 10
23+
#define PCLK (APB2_MHZ * 1000000)
2324
#else
2425
#define usart usart3
2526
#define USART_IRQ USART3_IRQ
2627
#define usart_gpio gpioc
2728
#define usart_tx_pin 10
2829
#define usart_rx_pin 11
30+
#define PCLK (APB1_MHZ * 1000000)
2931
#endif
3032

3133
/* Normally flush to serial is asynchronously executed in a low-pri IRQ. */
@@ -147,7 +149,7 @@ void console_init(void)
147149
#endif
148150

149151
/* BAUD, 8n1. */
150-
usart->brr = (APB2_MHZ * 1000000) / BAUD;
152+
usart->brr = PCLK / BAUD;
151153
usart->cr1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
152154
usart->cr3 = 0;
153155

src/display/lcd_stm32f105.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ const static struct i2c_cfg {
7474
#define SCL i2c_cfg->scl
7575
#define SDA i2c_cfg->sda
7676

77+
#define PCLK_MHZ APB1_MHZ
78+
7779
/* I2C error ISR. */
7880
#define I2C_ERROR_IRQ i2c_cfg->error_irq
7981
void IRQ_34(void) __attribute__((alias("IRQ_i2c_error")));
@@ -586,9 +588,9 @@ bool_t lcd_init(void)
586588

587589
/* Standard Mode (100kHz) */
588590
i2c->cr1 = 0;
589-
i2c->cr2 = I2C_CR2_FREQ(36);
590-
i2c->ccr = I2C_CCR_CCR(180);
591-
i2c->trise = 37;
591+
i2c->cr2 = I2C_CR2_FREQ(PCLK_MHZ);
592+
i2c->ccr = I2C_CCR_CCR(PCLK_MHZ*5);
593+
i2c->trise = (PCLK_MHZ <= 62) ? PCLK_MHZ + 1 : 63;
592594
i2c->cr1 = I2C_CR1_PE;
593595

594596
if (!reinit) {
@@ -1051,9 +1053,9 @@ static void oled_init_fast_mode(void)
10511053
i2c->cr1 = 0;
10521054

10531055
/* Fast Mode (400kHz). */
1054-
i2c->cr2 = I2C_CR2_FREQ(36);
1055-
i2c->ccr = I2C_CCR_FS | I2C_CCR_CCR(30);
1056-
i2c->trise = 12;
1056+
i2c->cr2 = I2C_CR2_FREQ(PCLK_MHZ);
1057+
i2c->ccr = I2C_CCR_FS | I2C_CCR_CCR(PCLK_MHZ*5/6);
1058+
i2c->trise = PCLK_MHZ*3/10 + 1;
10571059
i2c->cr1 = I2C_CR1_PE;
10581060
i2c->cr2 |= I2C_CR2_ITERREN;
10591061
}

src/mcu_stm32f105.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
* See the file COPYING for more details, or visit <http://unlicense.org>.
1010
*/
1111

12+
unsigned int sysclk_mhz = 72;
13+
unsigned int apb1_mhz = 36;
14+
1215
bool_t is_artery_mcu;
1316
unsigned int flash_page_size = FLASH_PAGE_SIZE;
1417
unsigned int ram_kb = 64;
@@ -32,35 +35,56 @@ static void identify_mcu(void)
3235
ram_kb = 32;
3336
if (flash_kb == 128)
3437
flash_page_size = 1024;
38+
sysclk_mhz = 144;
39+
apb1_mhz = 72;
3540
}
3641
}
3742

3843
static void clock_init(void)
3944
{
4045
/* Flash controller: reads require 2 wait states at 72MHz. */
41-
flash->acr = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY(2);
46+
flash->acr = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY(sysclk_mhz/32);
4247

4348
/* Start up the external oscillator. */
4449
rcc->cr |= RCC_CR_HSEON;
4550
while (!(rcc->cr & RCC_CR_HSERDY))
4651
cpu_relax();
4752

4853
/* PLLs, scalers, muxes. */
49-
rcc->cfgr = (RCC_CFGR_PLLMUL(9) | /* PLL = 9*8MHz = 72MHz */
50-
RCC_CFGR_PLLSRC_PREDIV1 |
51-
RCC_CFGR_ADCPRE_DIV8 |
52-
RCC_CFGR_PPRE1_DIV2);
54+
if (is_artery_mcu) {
55+
uint32_t rcc_pll = *RCC_PLL;
56+
rcc_pll &= ~(RCC_PLL_PLLCFGEN | RCC_PLL_FREF_MASK);
57+
rcc_pll |= RCC_PLL_FREF_8M;
58+
*RCC_PLL = rcc_pll;
59+
rcc->cfgr = (RCC_CFGR_PLLMUL_18 | /* PLL = 18*8MHz = 144MHz */
60+
RCC_CFGR_USBPSC_3 | /* USB = SYSCLK/3 = 48MHz */
61+
RCC_CFGR_PLLSRC_PREDIV1 |
62+
RCC_CFGR_ADCPRE_DIV8 |
63+
RCC_CFGR_APB2PSC_2 | /* APB2 = SYSCLK/2 = 72MHz */
64+
RCC_CFGR_APB1PSC_2); /* APB1 = SYSCLK/2 = 72MHz */
65+
} else {
66+
rcc->cfgr = (RCC_CFGR_PLLMUL(9) | /* PLL = 9*8MHz = 72MHz */
67+
RCC_CFGR_PLLSRC_PREDIV1 |
68+
RCC_CFGR_ADCPRE_DIV8 |
69+
RCC_CFGR_APB1PSC_2); /* APB1 = SYSCLK/2 = 36MHz */
70+
}
5371

5472
/* Enable and stabilise the PLL. */
5573
rcc->cr |= RCC_CR_PLLON;
5674
while (!(rcc->cr & RCC_CR_PLLRDY))
5775
cpu_relax();
5876

77+
if (is_artery_mcu)
78+
*RCC_MISC2 |= RCC_MISC2_AUTOSTEP_EN;
79+
5980
/* Switch to the externally-driven PLL for system clock. */
6081
rcc->cfgr |= RCC_CFGR_SW_PLL;
6182
while ((rcc->cfgr & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL)
6283
cpu_relax();
6384

85+
if (is_artery_mcu)
86+
*RCC_MISC2 &= ~RCC_MISC2_AUTOSTEP_EN;
87+
6488
/* Internal oscillator no longer needed. */
6589
rcc->cr &= ~RCC_CR_HSION;
6690
}

src/sd_spi.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,9 @@
99
* See the file COPYING for more details, or visit <http://unlicense.org>.
1010
*/
1111

12-
#if MCU == STM32F105
13-
/* Default Speed (25MHz). Closest we can get is 36Mhz/2 = 18MHz. */
14-
#define INIT_SPEED_DIV SPI_BR_DIV128 /* ~281kHz (<400kHz) */
15-
#define DEFAULT_SPEED_DIV SPI_BR_DIV2 /* 18MHz */
16-
#elif MCU == AT32F435
17-
/* Default Speed (25MHz). Closest we can get is 144Mhz/8 = 18MHz. */
18-
#define INIT_SPEED_DIV SPI_BR_DIV512 /* ~281kHz (<400kHz) */
19-
#define DEFAULT_SPEED_DIV SPI_BR_DIV8 /* 18MHz */
20-
#endif
12+
#define PCLK_MHZ APB1_MHZ
13+
#define INIT_SPEED_KHZ 400
14+
#define DEFAULT_SPEED_KHZ 25000
2115
#define SPI_PIN_SPEED _50MHz
2216

2317
#if 0
@@ -270,8 +264,16 @@ static bool_t sd_inserted(void)
270264
return gpio_read_pin(gpioc, 9);
271265
}
272266

273-
static void sd_spi_set_cr(uint32_t cr1, uint32_t br)
267+
static void sd_spi_set_cr(uint32_t cr1, unsigned int max_khz)
274268
{
269+
/* Set the divisor to satisfy maximum communications frequency. */
270+
uint32_t br = SPI_BR_DIV2;
271+
unsigned int khz = (PCLK_MHZ * 1000) >> 1;
272+
while (khz > max_khz) {
273+
khz >>= 1;
274+
br++;
275+
}
276+
275277
/* BR is called MDIV in AT32F435 documentation, and is extended by one
276278
* bit which resides in CR2. */
277279
spi->cr2 = (br & 8) << (8 - 3); /* CR2[8] := MDIV[3] */
@@ -314,7 +316,7 @@ static DSTATUS sd_disk_initialize(BYTE pdrv)
314316
cr1 = (SPI_CR1_MSTR | /* master */
315317
SPI_CR1_SSM | SPI_CR1_SSI | /* software NSS */
316318
SPI_CR1_SPE);
317-
sd_spi_set_cr(cr1, INIT_SPEED_DIV);
319+
sd_spi_set_cr(cr1, INIT_SPEED_KHZ);
318320

319321
/* Drain SPI I/O. */
320322
spi_quiesce(spi);
@@ -396,7 +398,7 @@ static DSTATUS sd_disk_initialize(BYTE pdrv)
396398

397399
if (!(status & STA_NOINIT)) {
398400
delay_us(10); /* XXX small delay here stops SPI getting stuck?? */
399-
sd_spi_set_cr(cr1, DEFAULT_SPEED_DIV);
401+
sd_spi_set_cr(cr1, DEFAULT_SPEED_KHZ);
400402
printk("SD Card configured\n");
401403
dump_cid_info();
402404
} else {

0 commit comments

Comments
 (0)