Page 12 of 17
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 7:37 am
by JohnLittle
Hey @OutoftheBOTS_
a native solution based on your C code would of course be the best solution, but would a micropython implementation be fast enough to get started?
I've been playing with jupyter notebook +
micropython remote ( +
vim-binding ) and have started converting your code.
This is way more advanced than the usual stuff I do with micropython but a good opportunity to learn.
I
suppose I need to use machine.mem16() and machine.mem8() here, I could be wrong though! Also, I would love to use some kind of loop in TFT_Init() but the addresses being poked alternate randomely between LCD_RAM and LCD_REG, so I couldn't think of one. I'll check some existing code for inspiration!
Cheers,
John
Code: Select all
import stm
import time
import machine
LCD_REG = const(0x60000000)
LCD_RAM = const(0x60020000)
def TFT_Init():
BIT12 = const(1 << 12)
_BIT12 = const(0xFFFF ^ BIT12)
#hardware reset
machine.mem16[stm.GPIO_ODR] &= _BIT12
time.sleep_ms(250)
machine.mem16[stm.GPIO_ODR] |= BIT12
time.sleep_ms(120)
#SOFTWARE RESET
machine.mem8[LCD_REG] = 0x01
time.sleep_ms(1000)
#POWER CONTROL A
machine.mem8[LCD_REG] = 0xCB
machine.mem8[LCD_RAM] = 0x39
machine.mem8[LCD_RAM] = 0x2C
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x34
machine.mem8[LCD_RAM] = 0x02
...
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 2:35 pm
by DJShadow1966
Hello John
Been working on this too and have a lot of code already written stuck on some :-
Code: Select all
void FSMC_Init(void){
//enable RCC for FSMC and both GPIO ports
RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN;
and
Code: Select all
//setup FSMC on Bank1 NORSRAM1
//setup timings of FSCM
FSMC_Bank1->BTCR[1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;
// Bank1 NOR/SRAM control register configuration
FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
Currently my code is :-
Code: Select all
import stm
import time
import machine
stm.RCC_AHB3ENR |=
stm.RCC_AHB3ENR |=
stm.RCC_AHB1ENR |= [stm.RCC_AHB1ENR
machine.mem16[stm.GPIOD + stm.GPIO_MODER] = 0b1100111110110011
machine.mem16[stm.GPIOE + stm.GPIO_MODER] = 0b1111111110000000
machine.mem16[stm.GPIOD + stm.GPIO_OTYPER] &= 0b0011000001001100
machine.mem16[stm.GPIOE + stm.GPIO_OTYPER] &= 0b0000000001111111
machine.mem16[stm.GPIOD + stm.GPIO_OSPEEDR] |= (0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOE + stm.GPIO_OSPEEDR] |= (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*12)) | (0b11<<(2*13)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOD + stm.GPIO_PUPDR] &= ((0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*6)) | (0b11<<(2*12)) | (0b11<<(2*13)))
machine.mem16[stm.GPIOE + stm.GPIO_PUPDR] &= ((0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*6)))
machine.mem16[stm.GPIOD + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7)
machine.mem16[stm.GPIOD + stm.GPIO_AFR1] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR1] & (0b1111<<(4*(13-8)) | 0b1111<<(4*(12-8)))) | 0b1100<<(4*(8-8)) | 0b1100<<(4*(9-8)) | 0b1100<<(4*(10-8)) | 0b1100<<(4*(11-8)) | 0b1100<<(4*(14-8)) | 0b1100<<(4*(15-8))
machine.mem16[stm.GPIOE + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOE + stm.GPIO_AFR0] & ~(0b1111<<7)) | 0b1100<<(4*7)
machine.mem16[stm.GPIOE + stm.GPIO_AFR1] = 0xCCCCCCCC
LCD_REG = const(0x60000000)
LCD_RAM = const(0x60040000)
def TFT_Init():
BIT12 = const(1 << 12)
_BIT12 = const(0xFFFF ^ BIT12)
#hardware reset
machine.mem16[stm.GPIO_ODR] &= _BIT12
time.sleep_ms(250)
machine.mem16[stm.GPIO_ODR] |= BIT12
time.sleep_ms(120)
#SOFTWARE RESET
machine.mem8[LCD_REG] = 0x01
time.sleep_ms(1000)
#POWER CONTROL A
machine.mem8[LCD_REG] = 0xCB
machine.mem8[LCD_RAM] = 0x39
machine.mem8[LCD_RAM] = 0x2C
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x34
machine.mem8[LCD_RAM] = 0x02
#DRIVER TIMING CONTROL A
machine.mem8[LCD_REG] = 0xE8
machine.mem8[LCD_RAM] = 0x85
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x78
#DRIVER TIMING CONTROL B
machine.mem8[LCD_REG] = 0xEA
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x00
#POWER ON SEQUENCE CONTROL
machine.mem8[LCD_REG] = 0xED
machine.mem8[LCD_RAM] = 0x64
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x12
machine.mem8[LCD_RAM] = 0x81
#PUMP RATIO CONTROL
machine.mem8[LCD_REG] = 0xF7
machine.mem8[LCD_RAM] = 0x20
#POWER CONTROL,VRH[5:0]
machine.mem8[LCD_REG] = 0xC0
machine.mem8[LCD_RAM] = 0x23
#POWER CONTROL,SAP[2:0]BT[3:0]
machine.mem8[LCD_REG] = 0xC1
machine.mem8[LCD_RAM] = 0x10
#VCM CONTROL
machine.mem8[LCD_REG] = 0xC5
machine.mem8[LCD_RAM] = 0x3E
machine.mem8[LCD_RAM] = 0x28
#VCM CONTROL 2
machine.mem8[LCD_REG] = 0xC7
machine.mem8[LCD_RAM] = 0x86
#MEMORY ACCESS CONTROL
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0x48
#PIXEL FORMAT
machine.mem8[LCD_REG] = 0x3A
machine.mem8[LCD_RAM] = 0x55
#FRAME RATIO CONTROL, STANDARD RGB COLOR
machine.mem8[LCD_REG] = 0xB1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x18
#DISPLAY FUNCTION CONTROL
machine.mem8[LCD_REG] = 0xB6
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x82
machine.mem8[LCD_RAM] = 0x27
#3GAMMA FUNCTION DISABLE
machine.mem8[LCD_REG] = 0xF2
machine.mem8[LCD_RAM] = 0x00
#GAMMA CURVE SELECTED
machine.mem8[LCD_REG] = 0x26
machine.mem8[LCD_RAM] = 0x01
#POSITIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE0
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x2B
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x4E
machine.mem8[LCD_RAM] = 0xF1
machine.mem8[LCD_RAM] = 0x37
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x10
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x09
machine.mem8[LCD_RAM] = 0x00
#NEGATIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x14
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x11
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0xC1
machine.mem8[LCD_RAM] = 0x48
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x36
machine.mem8[LCD_RAM] = 0x0F
#EXIT SLEEP
machine.mem8[LCD_REG] = 0x11
time.sleep_ms(120)
#TURN ON DISPLAY
machine.mem8[LCD_REG] = 0x29
#dispaly inversion
#machine.mem8[LCD_REG] = 0x21
#setup Memory Access Control
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0b00111111
def ILI9341_Set_Address(X1, Y1, X2, Y2):
#set X min and max
machine.mem8[LCD_REG] = 0x2A
machine.mem16[LCD_RAM] = X1>>8
machine.mem16[LCD_RAM] = X1
machine.mem16[LCD_RAM] = X2>>8
machine.mem16[LCD_RAM] = X2
#set y min and max
machine.mem8[LCD_REG] = 0x2B
machine.mem16[LCD_RAM] = Y1>>8
machine.mem16[LCD_RAM] = Y1
machine.mem16[LCD_RAM] = Y2>>8
machine.mem16[LCD_RAM] = Y2
#write data command
machine.mem8[LCD_REG] = 0x2C
def draw_pixel(X, Y, colour):
ILI9341_Set_Address(X, Y, X, Y)
machine.mem16[LCD_RAM] = colour
The rest I too have seem to got right following on from the snippet you included.
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 4:53 pm
by JohnLittle
Wow, that's amazing, thanks for doing this!
I wonder if jupyter + micropython can be shared somehow to avoid duplicating work, I seem to have typed exactly the same thing.
For reference, help(stm) outputs the following (see below), so the register address is stm.RCC_AHB3ENR and FSMEN (according to
the reference page 166) is bit 0.
For RCC_AHB1ENR, GPIODEN is bit 3 and GPIOEEN bit 4 (page 165).
Code: Select all
object <module 'stm'> is of type module
__name__ -- stm
mem8 -- <8-bit memory>
mem16 -- <16-bit memory>
mem32 -- <32-bit memory>
TIM2 -- 1073741824
TIM3 -- 1073742848
TIM4 -- 1073743872
TIM5 -- 1073744896
TIM6 -- 1073745920
TIM7 -- 1073746944
TIM12 -- 1073747968
TIM13 -- 1073748992
TIM14 -- 1073750016
RTC -- 1073752064
WWDG -- 1073753088
IWDG -- 1073754112
I2S2EXT -- 1073755136
SPI2 -- 1073756160
SPI3 -- 1073757184
I2S3EXT -- 1073758208
USART2 -- 1073759232
USART3 -- 1073760256
UART4 -- 1073761280
UART5 -- 1073762304
I2C1 -- 1073763328
I2C2 -- 1073764352
I2C3 -- 1073765376
CAN1 -- 1073767424
CAN2 -- 1073768448
PWR -- 1073770496
DAC1 -- 1073771520
DAC -- 1073771520
TIM1 -- 1073807360
TIM8 -- 1073808384
USART1 -- 1073811456
USART6 -- 1073812480
ADC1 -- 1073815552
ADC2 -- 1073815808
ADC3 -- 1073816064
ADC123_COMMON -- 1073816320
SDIO -- 1073818624
SPI1 -- 1073819648
SYSCFG -- 1073821696
EXTI -- 1073822720
TIM9 -- 1073823744
TIM10 -- 1073824768
TIM11 -- 1073825792
GPIOA -- 1073872896
GPIOB -- 1073873920
GPIOC -- 1073874944
GPIOD -- 1073875968
GPIOE -- 1073876992
GPIOF -- 1073878016
GPIOG -- 1073879040
GPIOH -- 1073880064
GPIOI -- 1073881088
CRC -- 1073885184
RCC -- 1073887232
FLASH -- 1073888256
DMA1 -- 1073897472
DMA2 -- 1073898496
ETH -- 1073905664
DCMI -- 1342504960
RNG -- 1342572544
DBGMCU -- 3758366720
ADC_SR -- 0
ADC_CR1 -- 4
ADC_CR2 -- 8
ADC_SMPR1 -- 12
ADC_SMPR2 -- 16
ADC_JOFR1 -- 20
ADC_JOFR2 -- 24
ADC_JOFR3 -- 28
ADC_JOFR4 -- 32
ADC_HTR -- 36
ADC_LTR -- 40
ADC_SQR1 -- 44
ADC_SQR2 -- 48
ADC_SQR3 -- 52
ADC_JSQR -- 56
ADC_JDR1 -- 60
ADC_JDR2 -- 64
ADC_JDR3 -- 68
ADC_JDR4 -- 72
ADC_DR -- 76
CRC_DR -- 0
CRC_IDR -- 4
CRC_CR -- 8
DAC_CR -- 0
DAC_SWTRIGR -- 4
DAC_DHR12R1 -- 8
DAC_DHR12L1 -- 12
DAC_DHR8R1 -- 16
DAC_DHR12R2 -- 20
DAC_DHR12L2 -- 24
DAC_DHR8R2 -- 28
DAC_DHR12RD -- 32
DAC_DHR12LD -- 36
DAC_DHR8RD -- 40
DAC_DOR1 -- 44
DAC_DOR2 -- 48
DAC_SR -- 52
DBGMCU_IDCODE -- 0
DBGMCU_CR -- 4
DBGMCU_APB1FZ -- 8
DBGMCU_APB2FZ -- 12
DMA_LISR -- 0
DMA_HISR -- 4
DMA_LIFCR -- 8
DMA_HIFCR -- 12
EXTI_IMR -- 0
EXTI_EMR -- 4
EXTI_RTSR -- 8
EXTI_FTSR -- 12
EXTI_SWIER -- 16
EXTI_PR -- 20
FLASH_ACR -- 0
FLASH_KEYR -- 4
FLASH_OPTKEYR -- 8
FLASH_SR -- 12
FLASH_CR -- 16
FLASH_OPTCR -- 20
FLASH_OPTCR1 -- 24
GPIO_MODER -- 0
GPIO_OTYPER -- 4
GPIO_OSPEEDR -- 8
GPIO_PUPDR -- 12
GPIO_IDR -- 16
GPIO_ODR -- 20
GPIO_BSRR -- 24
GPIO_LCKR -- 28
GPIO_AFR0 -- 32
GPIO_AFR1 -- 36
GPIO_BSRRL -- 24
GPIO_BSRRH -- 26
SYSCFG_MEMRMP -- 0
SYSCFG_PMC -- 4
SYSCFG_EXTICR0 -- 8
SYSCFG_EXTICR1 -- 12
SYSCFG_EXTICR2 -- 16
SYSCFG_EXTICR3 -- 20
SYSCFG_CMPCR -- 32
I2C_CR1 -- 0
I2C_CR2 -- 4
I2C_OAR1 -- 8
I2C_OAR2 -- 12
I2C_DR -- 16
I2C_SR1 -- 20
I2C_SR2 -- 24
I2C_CCR -- 28
I2C_TRISE -- 32
IWDG_KR -- 0
IWDG_PR -- 4
IWDG_RLR -- 8
IWDG_SR -- 12
PWR_CR -- 0
PWR_CSR -- 4
RCC_CR -- 0
RCC_PLLCFGR -- 4
RCC_CFGR -- 8
RCC_CIR -- 12
RCC_AHB1RSTR -- 16
RCC_AHB2RSTR -- 20
RCC_AHB3RSTR -- 24
RCC_APB1RSTR -- 32
RCC_APB2RSTR -- 36
RCC_AHB1ENR -- 48
RCC_AHB2ENR -- 52
RCC_AHB3ENR -- 56
RCC_APB1ENR -- 64
RCC_APB2ENR -- 68
RCC_AHB1LPENR -- 80
RCC_AHB2LPENR -- 84
RCC_AHB3LPENR -- 88
RCC_APB1LPENR -- 96
RCC_APB2LPENR -- 100
RCC_BDCR -- 112
RCC_CSR -- 116
RCC_SSCGR -- 128
RCC_PLLI2SCFGR -- 132
RTC_TR -- 0
RTC_DR -- 4
RTC_CR -- 8
RTC_ISR -- 12
RTC_PRER -- 16
RTC_WUTR -- 20
RTC_CALIBR -- 24
RTC_ALRMAR -- 28
RTC_ALRMBR -- 32
RTC_WPR -- 36
RTC_SSR -- 40
RTC_SHIFTR -- 44
RTC_TSTR -- 48
RTC_TSDR -- 52
RTC_TSSSR -- 56
RTC_CALR -- 60
RTC_TAFCR -- 64
RTC_ALRMASSR -- 68
RTC_ALRMBSSR -- 72
RTC_BKP0R -- 80
RTC_BKP1R -- 84
RTC_BKP2R -- 88
RTC_BKP3R -- 92
RTC_BKP4R -- 96
RTC_BKP5R -- 100
RTC_BKP6R -- 104
RTC_BKP7R -- 108
RTC_BKP8R -- 112
RTC_BKP9R -- 116
RTC_BKP10R -- 120
RTC_BKP11R -- 124
RTC_BKP12R -- 128
RTC_BKP13R -- 132
RTC_BKP14R -- 136
RTC_BKP15R -- 140
RTC_BKP16R -- 144
RTC_BKP17R -- 148
RTC_BKP18R -- 152
RTC_BKP19R -- 156
SPI_CR1 -- 0
SPI_CR2 -- 4
SPI_SR -- 8
SPI_DR -- 12
SPI_CRCPR -- 16
SPI_RXCRCR -- 20
SPI_TXCRCR -- 24
SPI_I2SCFGR -- 28
SPI_I2SPR -- 32
TIM_CR1 -- 0
TIM_CR2 -- 4
TIM_SMCR -- 8
TIM_DIER -- 12
TIM_SR -- 16
TIM_EGR -- 20
TIM_CCMR1 -- 24
TIM_CCMR2 -- 28
TIM_CCER -- 32
TIM_CNT -- 36
TIM_PSC -- 40
TIM_ARR -- 44
TIM_RCR -- 48
TIM_CCR1 -- 52
TIM_CCR2 -- 56
TIM_CCR3 -- 60
TIM_CCR4 -- 64
TIM_BDTR -- 68
TIM_DCR -- 72
TIM_DMAR -- 76
TIM_OR -- 80
USART_SR -- 0
USART_DR -- 4
USART_BRR -- 8
USART_CR1 -- 12
USART_CR2 -- 16
USART_CR3 -- 20
USART_GTPR -- 24
WWDG_CR -- 0
WWDG_CFR -- 4
WWDG_SR -- 8
RNG_CR -- 0
RNG_SR -- 4
RNG_DR -- 8
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 6:23 pm
by DJShadow1966
Hello John
Many thanks I am pretty much have a similar background to yourself, started programming in Machine code on Z80 CPU some years ago when I was 14 pretty much self taught until mid 20's, still do some machine code, but getting on an memory doesn't work so good.
Getting further on in the code should have something pretty workable by the end of week.
Regards Mike
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 8:44 pm
by OutoftheBOTS_
JohnLittle wrote: ↑Sun Jul 21, 2019 4:53 pm
Wow, that's amazing, thanks for doing this!
I wonder if jupyter + micropython can be shared somehow to avoid duplicating work, I seem to have typed exactly the same thing.
For reference, help(stm) outputs the following (see below), so the register address is stm.RCC_AHB3ENR and FSMEN (according to
the reference page 166) is bit 0.
For RCC_AHB1ENR, GPIODEN is bit 3 and GPIOEEN bit 4 (page 165).
Code: Select all
object <module 'stm'> is of type module
__name__ -- stm
mem8 -- <8-bit memory>
mem16 -- <16-bit memory>
mem32 -- <32-bit memory>
TIM2 -- 1073741824
TIM3 -- 1073742848
TIM4 -- 1073743872
TIM5 -- 1073744896
TIM6 -- 1073745920
TIM7 -- 1073746944
TIM12 -- 1073747968
TIM13 -- 1073748992
TIM14 -- 1073750016
RTC -- 1073752064
WWDG -- 1073753088
IWDG -- 1073754112
I2S2EXT -- 1073755136
SPI2 -- 1073756160
SPI3 -- 1073757184
I2S3EXT -- 1073758208
USART2 -- 1073759232
USART3 -- 1073760256
UART4 -- 1073761280
UART5 -- 1073762304
I2C1 -- 1073763328
I2C2 -- 1073764352
I2C3 -- 1073765376
CAN1 -- 1073767424
CAN2 -- 1073768448
PWR -- 1073770496
DAC1 -- 1073771520
DAC -- 1073771520
TIM1 -- 1073807360
TIM8 -- 1073808384
USART1 -- 1073811456
USART6 -- 1073812480
ADC1 -- 1073815552
ADC2 -- 1073815808
ADC3 -- 1073816064
ADC123_COMMON -- 1073816320
SDIO -- 1073818624
SPI1 -- 1073819648
SYSCFG -- 1073821696
EXTI -- 1073822720
TIM9 -- 1073823744
TIM10 -- 1073824768
TIM11 -- 1073825792
GPIOA -- 1073872896
GPIOB -- 1073873920
GPIOC -- 1073874944
GPIOD -- 1073875968
GPIOE -- 1073876992
GPIOF -- 1073878016
GPIOG -- 1073879040
GPIOH -- 1073880064
GPIOI -- 1073881088
CRC -- 1073885184
RCC -- 1073887232
FLASH -- 1073888256
DMA1 -- 1073897472
DMA2 -- 1073898496
ETH -- 1073905664
DCMI -- 1342504960
RNG -- 1342572544
DBGMCU -- 3758366720
ADC_SR -- 0
ADC_CR1 -- 4
ADC_CR2 -- 8
ADC_SMPR1 -- 12
ADC_SMPR2 -- 16
ADC_JOFR1 -- 20
ADC_JOFR2 -- 24
ADC_JOFR3 -- 28
ADC_JOFR4 -- 32
ADC_HTR -- 36
ADC_LTR -- 40
ADC_SQR1 -- 44
ADC_SQR2 -- 48
ADC_SQR3 -- 52
ADC_JSQR -- 56
ADC_JDR1 -- 60
ADC_JDR2 -- 64
ADC_JDR3 -- 68
ADC_JDR4 -- 72
ADC_DR -- 76
CRC_DR -- 0
CRC_IDR -- 4
CRC_CR -- 8
DAC_CR -- 0
DAC_SWTRIGR -- 4
DAC_DHR12R1 -- 8
DAC_DHR12L1 -- 12
DAC_DHR8R1 -- 16
DAC_DHR12R2 -- 20
DAC_DHR12L2 -- 24
DAC_DHR8R2 -- 28
DAC_DHR12RD -- 32
DAC_DHR12LD -- 36
DAC_DHR8RD -- 40
DAC_DOR1 -- 44
DAC_DOR2 -- 48
DAC_SR -- 52
DBGMCU_IDCODE -- 0
DBGMCU_CR -- 4
DBGMCU_APB1FZ -- 8
DBGMCU_APB2FZ -- 12
DMA_LISR -- 0
DMA_HISR -- 4
DMA_LIFCR -- 8
DMA_HIFCR -- 12
EXTI_IMR -- 0
EXTI_EMR -- 4
EXTI_RTSR -- 8
EXTI_FTSR -- 12
EXTI_SWIER -- 16
EXTI_PR -- 20
FLASH_ACR -- 0
FLASH_KEYR -- 4
FLASH_OPTKEYR -- 8
FLASH_SR -- 12
FLASH_CR -- 16
FLASH_OPTCR -- 20
FLASH_OPTCR1 -- 24
GPIO_MODER -- 0
GPIO_OTYPER -- 4
GPIO_OSPEEDR -- 8
GPIO_PUPDR -- 12
GPIO_IDR -- 16
GPIO_ODR -- 20
GPIO_BSRR -- 24
GPIO_LCKR -- 28
GPIO_AFR0 -- 32
GPIO_AFR1 -- 36
GPIO_BSRRL -- 24
GPIO_BSRRH -- 26
SYSCFG_MEMRMP -- 0
SYSCFG_PMC -- 4
SYSCFG_EXTICR0 -- 8
SYSCFG_EXTICR1 -- 12
SYSCFG_EXTICR2 -- 16
SYSCFG_EXTICR3 -- 20
SYSCFG_CMPCR -- 32
I2C_CR1 -- 0
I2C_CR2 -- 4
I2C_OAR1 -- 8
I2C_OAR2 -- 12
I2C_DR -- 16
I2C_SR1 -- 20
I2C_SR2 -- 24
I2C_CCR -- 28
I2C_TRISE -- 32
IWDG_KR -- 0
IWDG_PR -- 4
IWDG_RLR -- 8
IWDG_SR -- 12
PWR_CR -- 0
PWR_CSR -- 4
RCC_CR -- 0
RCC_PLLCFGR -- 4
RCC_CFGR -- 8
RCC_CIR -- 12
RCC_AHB1RSTR -- 16
RCC_AHB2RSTR -- 20
RCC_AHB3RSTR -- 24
RCC_APB1RSTR -- 32
RCC_APB2RSTR -- 36
RCC_AHB1ENR -- 48
RCC_AHB2ENR -- 52
RCC_AHB3ENR -- 56
RCC_APB1ENR -- 64
RCC_APB2ENR -- 68
RCC_AHB1LPENR -- 80
RCC_AHB2LPENR -- 84
RCC_AHB3LPENR -- 88
RCC_APB1LPENR -- 96
RCC_APB2LPENR -- 100
RCC_BDCR -- 112
RCC_CSR -- 116
RCC_SSCGR -- 128
RCC_PLLI2SCFGR -- 132
RTC_TR -- 0
RTC_DR -- 4
RTC_CR -- 8
RTC_ISR -- 12
RTC_PRER -- 16
RTC_WUTR -- 20
RTC_CALIBR -- 24
RTC_ALRMAR -- 28
RTC_ALRMBR -- 32
RTC_WPR -- 36
RTC_SSR -- 40
RTC_SHIFTR -- 44
RTC_TSTR -- 48
RTC_TSDR -- 52
RTC_TSSSR -- 56
RTC_CALR -- 60
RTC_TAFCR -- 64
RTC_ALRMASSR -- 68
RTC_ALRMBSSR -- 72
RTC_BKP0R -- 80
RTC_BKP1R -- 84
RTC_BKP2R -- 88
RTC_BKP3R -- 92
RTC_BKP4R -- 96
RTC_BKP5R -- 100
RTC_BKP6R -- 104
RTC_BKP7R -- 108
RTC_BKP8R -- 112
RTC_BKP9R -- 116
RTC_BKP10R -- 120
RTC_BKP11R -- 124
RTC_BKP12R -- 128
RTC_BKP13R -- 132
RTC_BKP14R -- 136
RTC_BKP15R -- 140
RTC_BKP16R -- 144
RTC_BKP17R -- 148
RTC_BKP18R -- 152
RTC_BKP19R -- 156
SPI_CR1 -- 0
SPI_CR2 -- 4
SPI_SR -- 8
SPI_DR -- 12
SPI_CRCPR -- 16
SPI_RXCRCR -- 20
SPI_TXCRCR -- 24
SPI_I2SCFGR -- 28
SPI_I2SPR -- 32
TIM_CR1 -- 0
TIM_CR2 -- 4
TIM_SMCR -- 8
TIM_DIER -- 12
TIM_SR -- 16
TIM_EGR -- 20
TIM_CCMR1 -- 24
TIM_CCMR2 -- 28
TIM_CCER -- 32
TIM_CNT -- 36
TIM_PSC -- 40
TIM_ARR -- 44
TIM_RCR -- 48
TIM_CCR1 -- 52
TIM_CCR2 -- 56
TIM_CCR3 -- 60
TIM_CCR4 -- 64
TIM_BDTR -- 68
TIM_DCR -- 72
TIM_DMAR -- 76
TIM_OR -- 80
USART_SR -- 0
USART_DR -- 4
USART_BRR -- 8
USART_CR1 -- 12
USART_CR2 -- 16
USART_CR3 -- 20
USART_GTPR -- 24
WWDG_CR -- 0
WWDG_CFR -- 4
WWDG_SR -- 8
RNG_CR -- 0
RNG_SR -- 4
RNG_DR -- 8
Ok you guys are making great progress and are likely to it working using just a pure python implementation.
I do notice that the reference manual quoted above is for the STM32F7 not the STMF407 do be aware the registers are different between the 2 MCUs and I believe this is why the authors of MP use the HAL libraries so to make code more portable between the MCUs.
Use this refernce manual for the STMF4
https://www.st.com/content/ccc/resource ... 031020.pdf
Also if you want to see the exact memory addresses that I have used you can always look at the maco definitions in STM32F4xx.h
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 9:09 pm
by OutoftheBOTS_
DJShadow1966 wrote: ↑Sun Jul 21, 2019 2:35 pm
Hello John
Been working on this too and have a lot of code already written stuck on some :-
Code: Select all
void FSMC_Init(void){
//enable RCC for FSMC and both GPIO ports
RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN;
and
Code: Select all
//setup FSMC on Bank1 NORSRAM1
//setup timings of FSCM
FSMC_Bank1->BTCR[1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;
// Bank1 NOR/SRAM control register configuration
FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
Currently my code is :-
Code: Select all
import stm
import time
import machine
stm.RCC_AHB3ENR |=
stm.RCC_AHB3ENR |=
stm.RCC_AHB1ENR |= [stm.RCC_AHB1ENR
machine.mem16[stm.GPIOD + stm.GPIO_MODER] = 0b1100111110110011
machine.mem16[stm.GPIOE + stm.GPIO_MODER] = 0b1111111110000000
machine.mem16[stm.GPIOD + stm.GPIO_OTYPER] &= 0b0011000001001100
machine.mem16[stm.GPIOE + stm.GPIO_OTYPER] &= 0b0000000001111111
machine.mem16[stm.GPIOD + stm.GPIO_OSPEEDR] |= (0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOE + stm.GPIO_OSPEEDR] |= (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*12)) | (0b11<<(2*13)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOD + stm.GPIO_PUPDR] &= ((0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*6)) | (0b11<<(2*12)) | (0b11<<(2*13)))
machine.mem16[stm.GPIOE + stm.GPIO_PUPDR] &= ((0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*6)))
machine.mem16[stm.GPIOD + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7)
machine.mem16[stm.GPIOD + stm.GPIO_AFR1] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR1] & (0b1111<<(4*(13-8)) | 0b1111<<(4*(12-8)))) | 0b1100<<(4*(8-8)) | 0b1100<<(4*(9-8)) | 0b1100<<(4*(10-8)) | 0b1100<<(4*(11-8)) | 0b1100<<(4*(14-8)) | 0b1100<<(4*(15-8))
machine.mem16[stm.GPIOE + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOE + stm.GPIO_AFR0] & ~(0b1111<<7)) | 0b1100<<(4*7)
machine.mem16[stm.GPIOE + stm.GPIO_AFR1] = 0xCCCCCCCC
LCD_REG = const(0x60000000)
LCD_RAM = const(0x60040000)
def TFT_Init():
BIT12 = const(1 << 12)
_BIT12 = const(0xFFFF ^ BIT12)
#hardware reset
machine.mem16[stm.GPIO_ODR] &= _BIT12
time.sleep_ms(250)
machine.mem16[stm.GPIO_ODR] |= BIT12
time.sleep_ms(120)
#SOFTWARE RESET
machine.mem8[LCD_REG] = 0x01
time.sleep_ms(1000)
#POWER CONTROL A
machine.mem8[LCD_REG] = 0xCB
machine.mem8[LCD_RAM] = 0x39
machine.mem8[LCD_RAM] = 0x2C
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x34
machine.mem8[LCD_RAM] = 0x02
#DRIVER TIMING CONTROL A
machine.mem8[LCD_REG] = 0xE8
machine.mem8[LCD_RAM] = 0x85
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x78
#DRIVER TIMING CONTROL B
machine.mem8[LCD_REG] = 0xEA
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x00
#POWER ON SEQUENCE CONTROL
machine.mem8[LCD_REG] = 0xED
machine.mem8[LCD_RAM] = 0x64
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x12
machine.mem8[LCD_RAM] = 0x81
#PUMP RATIO CONTROL
machine.mem8[LCD_REG] = 0xF7
machine.mem8[LCD_RAM] = 0x20
#POWER CONTROL,VRH[5:0]
machine.mem8[LCD_REG] = 0xC0
machine.mem8[LCD_RAM] = 0x23
#POWER CONTROL,SAP[2:0]BT[3:0]
machine.mem8[LCD_REG] = 0xC1
machine.mem8[LCD_RAM] = 0x10
#VCM CONTROL
machine.mem8[LCD_REG] = 0xC5
machine.mem8[LCD_RAM] = 0x3E
machine.mem8[LCD_RAM] = 0x28
#VCM CONTROL 2
machine.mem8[LCD_REG] = 0xC7
machine.mem8[LCD_RAM] = 0x86
#MEMORY ACCESS CONTROL
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0x48
#PIXEL FORMAT
machine.mem8[LCD_REG] = 0x3A
machine.mem8[LCD_RAM] = 0x55
#FRAME RATIO CONTROL, STANDARD RGB COLOR
machine.mem8[LCD_REG] = 0xB1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x18
#DISPLAY FUNCTION CONTROL
machine.mem8[LCD_REG] = 0xB6
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x82
machine.mem8[LCD_RAM] = 0x27
#3GAMMA FUNCTION DISABLE
machine.mem8[LCD_REG] = 0xF2
machine.mem8[LCD_RAM] = 0x00
#GAMMA CURVE SELECTED
machine.mem8[LCD_REG] = 0x26
machine.mem8[LCD_RAM] = 0x01
#POSITIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE0
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x2B
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x4E
machine.mem8[LCD_RAM] = 0xF1
machine.mem8[LCD_RAM] = 0x37
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x10
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x09
machine.mem8[LCD_RAM] = 0x00
#NEGATIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x14
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x11
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0xC1
machine.mem8[LCD_RAM] = 0x48
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x36
machine.mem8[LCD_RAM] = 0x0F
#EXIT SLEEP
machine.mem8[LCD_REG] = 0x11
time.sleep_ms(120)
#TURN ON DISPLAY
machine.mem8[LCD_REG] = 0x29
#dispaly inversion
#machine.mem8[LCD_REG] = 0x21
#setup Memory Access Control
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0b00111111
def ILI9341_Set_Address(X1, Y1, X2, Y2):
#set X min and max
machine.mem8[LCD_REG] = 0x2A
machine.mem16[LCD_RAM] = X1>>8
machine.mem16[LCD_RAM] = X1
machine.mem16[LCD_RAM] = X2>>8
machine.mem16[LCD_RAM] = X2
#set y min and max
machine.mem8[LCD_REG] = 0x2B
machine.mem16[LCD_RAM] = Y1>>8
machine.mem16[LCD_RAM] = Y1
machine.mem16[LCD_RAM] = Y2>>8
machine.mem16[LCD_RAM] = Y2
#write data command
machine.mem8[LCD_REG] = 0x2C
def draw_pixel(X, Y, colour):
ILI9341_Set_Address(X, Y, X, Y)
machine.mem16[LCD_RAM] = colour
The rest I too have seem to got right following on from the snippet you included.
The STM32 has 32 bit registers so you will need to use machine.mem32[] to write to the STM32 registers then when writing to the TFT GRAM you will need to use machine.mem16[] as it write 16 bits of data at a time but when you write to the TFT control register you will need to use machine.mem8[] as the TFT only has 8 bit regiters
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Sun Jul 21, 2019 10:41 pm
by OutoftheBOTS_
Also when I wired up my TFT I mainly used the TFT header on the STM32F407VRT6 black except I used different pin for the RS/DC pin and reset pin.
On the header it connects the reset pin to the reset button on the board but I connected it to PD12 so that I could do a hardware reset in software so if your just using the pins on the TFT header then you won't need to setup PD12 and you won't need the first few lines in the init.
Also I used A16 (PD11) as the RS/DC pin because I wanted to wire the same as others had that were programming in MBed so I didn't connect my RS/DC pin on the TFT to the header but rather connected it to PD11 on the main break out header. The TFT header uses A18(PD13) as the RS/DC pin so this means in the code were it is setting up the pins to AF_FSMC you will need to change it so that it sets up PD13 instead of PD11.
Also you will of course need to then change the address of LCD_RAM. I used 0x60020000 because 0x60000000 (base address) + 0x20000 (A16) if you going to use the TFT header pins and A18 as your RS/DC then the LCD_RAM address will be 0x60080000. You will notice that those addresses seem to be 1 bit out and this confused me for ages before I got it to work but it seems in 16bit mode the STM maps (moves) the address bits to the side by 1 bit see following answer from the net
Turns out that address bits differ between 8-bit and 16-bit addressing mode. In 8-bit addressing it's mapped to bits [0-23] and in 16-bit to [1-24], so if you want to use A16 pin as CMD / DATA selection, the address of DATA transfer is 0x60010000 in 8-bit mode and 0x60020000 in 16-bit.
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Mon Jul 22, 2019 6:18 am
by OutoftheBOTS_
DJShadow1966 wrote: ↑Sun Jul 21, 2019 2:35 pm
Hello John
Been working on this too and have a lot of code already written stuck on some :-
Code: Select all
void FSMC_Init(void){
//enable RCC for FSMC and both GPIO ports
RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN;
and
Code: Select all
//setup FSMC on Bank1 NORSRAM1
//setup timings of FSCM
FSMC_Bank1->BTCR[1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;
// Bank1 NOR/SRAM control register configuration
FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
Currently my code is :-
Code: Select all
import stm
import time
import machine
stm.RCC_AHB3ENR |=
stm.RCC_AHB3ENR |=
stm.RCC_AHB1ENR |= [stm.RCC_AHB1ENR
machine.mem16[stm.GPIOD + stm.GPIO_MODER] = 0b1100111110110011
machine.mem16[stm.GPIOE + stm.GPIO_MODER] = 0b1111111110000000
machine.mem16[stm.GPIOD + stm.GPIO_OTYPER] &= 0b0011000001001100
machine.mem16[stm.GPIOE + stm.GPIO_OTYPER] &= 0b0000000001111111
machine.mem16[stm.GPIOD + stm.GPIO_OSPEEDR] |= (0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOE + stm.GPIO_OSPEEDR] |= (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*12)) | (0b11<<(2*13)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem16[stm.GPIOD + stm.GPIO_PUPDR] &= ((0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*6)) | (0b11<<(2*12)) | (0b11<<(2*13)))
machine.mem16[stm.GPIOE + stm.GPIO_PUPDR] &= ((0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*6)))
machine.mem16[stm.GPIOD + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7)
machine.mem16[stm.GPIOD + stm.GPIO_AFR1] = (machine.mem16[stm.GPIOD + stm.GPIO_AFR1] & (0b1111<<(4*(13-8)) | 0b1111<<(4*(12-8)))) | 0b1100<<(4*(8-8)) | 0b1100<<(4*(9-8)) | 0b1100<<(4*(10-8)) | 0b1100<<(4*(11-8)) | 0b1100<<(4*(14-8)) | 0b1100<<(4*(15-8))
machine.mem16[stm.GPIOE + stm.GPIO_AFR0] = (machine.mem16[stm.GPIOE + stm.GPIO_AFR0] & ~(0b1111<<7)) | 0b1100<<(4*7)
machine.mem16[stm.GPIOE + stm.GPIO_AFR1] = 0xCCCCCCCC
LCD_REG = const(0x60000000)
LCD_RAM = const(0x60040000)
def TFT_Init():
BIT12 = const(1 << 12)
_BIT12 = const(0xFFFF ^ BIT12)
#hardware reset
machine.mem16[stm.GPIO_ODR] &= _BIT12
time.sleep_ms(250)
machine.mem16[stm.GPIO_ODR] |= BIT12
time.sleep_ms(120)
#SOFTWARE RESET
machine.mem8[LCD_REG] = 0x01
time.sleep_ms(1000)
#POWER CONTROL A
machine.mem8[LCD_REG] = 0xCB
machine.mem8[LCD_RAM] = 0x39
machine.mem8[LCD_RAM] = 0x2C
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x34
machine.mem8[LCD_RAM] = 0x02
#DRIVER TIMING CONTROL A
machine.mem8[LCD_REG] = 0xE8
machine.mem8[LCD_RAM] = 0x85
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x78
#DRIVER TIMING CONTROL B
machine.mem8[LCD_REG] = 0xEA
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x00
#POWER ON SEQUENCE CONTROL
machine.mem8[LCD_REG] = 0xED
machine.mem8[LCD_RAM] = 0x64
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x12
machine.mem8[LCD_RAM] = 0x81
#PUMP RATIO CONTROL
machine.mem8[LCD_REG] = 0xF7
machine.mem8[LCD_RAM] = 0x20
#POWER CONTROL,VRH[5:0]
machine.mem8[LCD_REG] = 0xC0
machine.mem8[LCD_RAM] = 0x23
#POWER CONTROL,SAP[2:0]BT[3:0]
machine.mem8[LCD_REG] = 0xC1
machine.mem8[LCD_RAM] = 0x10
#VCM CONTROL
machine.mem8[LCD_REG] = 0xC5
machine.mem8[LCD_RAM] = 0x3E
machine.mem8[LCD_RAM] = 0x28
#VCM CONTROL 2
machine.mem8[LCD_REG] = 0xC7
machine.mem8[LCD_RAM] = 0x86
#MEMORY ACCESS CONTROL
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0x48
#PIXEL FORMAT
machine.mem8[LCD_REG] = 0x3A
machine.mem8[LCD_RAM] = 0x55
#FRAME RATIO CONTROL, STANDARD RGB COLOR
machine.mem8[LCD_REG] = 0xB1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x18
#DISPLAY FUNCTION CONTROL
machine.mem8[LCD_REG] = 0xB6
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x82
machine.mem8[LCD_RAM] = 0x27
#3GAMMA FUNCTION DISABLE
machine.mem8[LCD_REG] = 0xF2
machine.mem8[LCD_RAM] = 0x00
#GAMMA CURVE SELECTED
machine.mem8[LCD_REG] = 0x26
machine.mem8[LCD_RAM] = 0x01
#POSITIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE0
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x2B
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x4E
machine.mem8[LCD_RAM] = 0xF1
machine.mem8[LCD_RAM] = 0x37
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x10
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x09
machine.mem8[LCD_RAM] = 0x00
#NEGATIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE1
machine.mem8[LCD_RAM] = 0x00
machine.mem8[LCD_RAM] = 0x0E
machine.mem8[LCD_RAM] = 0x14
machine.mem8[LCD_RAM] = 0x03
machine.mem8[LCD_RAM] = 0x11
machine.mem8[LCD_RAM] = 0x07
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0xC1
machine.mem8[LCD_RAM] = 0x48
machine.mem8[LCD_RAM] = 0x08
machine.mem8[LCD_RAM] = 0x0F
machine.mem8[LCD_RAM] = 0x0C
machine.mem8[LCD_RAM] = 0x31
machine.mem8[LCD_RAM] = 0x36
machine.mem8[LCD_RAM] = 0x0F
#EXIT SLEEP
machine.mem8[LCD_REG] = 0x11
time.sleep_ms(120)
#TURN ON DISPLAY
machine.mem8[LCD_REG] = 0x29
#dispaly inversion
#machine.mem8[LCD_REG] = 0x21
#setup Memory Access Control
machine.mem8[LCD_REG] = 0x36
machine.mem8[LCD_RAM] = 0b00111111
def ILI9341_Set_Address(X1, Y1, X2, Y2):
#set X min and max
machine.mem8[LCD_REG] = 0x2A
machine.mem16[LCD_RAM] = X1>>8
machine.mem16[LCD_RAM] = X1
machine.mem16[LCD_RAM] = X2>>8
machine.mem16[LCD_RAM] = X2
#set y min and max
machine.mem8[LCD_REG] = 0x2B
machine.mem16[LCD_RAM] = Y1>>8
machine.mem16[LCD_RAM] = Y1
machine.mem16[LCD_RAM] = Y2>>8
machine.mem16[LCD_RAM] = Y2
#write data command
machine.mem8[LCD_REG] = 0x2C
def draw_pixel(X, Y, colour):
ILI9341_Set_Address(X, Y, X, Y)
machine.mem16[LCD_RAM] = colour
The rest I too have seem to got right following on from the snippet you included.
There might not be definitions already in MP for the FSMC register so we can define some. The couple we need start on page 1577 of the reference manual
https://www.st.com/content/ccc/resource ... 031020.pdf
The ones your stuck on should look something like this
Code: Select all
#constants of register
RCC_AHB3ENR_FSMCEN = 0x1 #bit to enable FSMC clock
RCC_AHB1ENR_GPIODEN = (0x1 << 3) #bit to enable D port clock
RCC_AHB1ENR_GPIOEEN = (0x1U << 4U) #bit to enable E port clock
FSMC_Bank1_base = 0xA0000000U # FSMC registers base address
FSMC_BCR_bank1_offset = 0x0
FSMC_BTR_bank1_offset = 0x04
FSMC_BTR1_ADDSET_1 = 0x2
FSMC_BTR1_DATAST_1 = (0x02 << 8)
FSMC_BCR1_MWID_0 = (0x1 << 4)
FSMC_BCR1_WREN = (0x1 << 12)
FSMC_BCR1_MBKEN = 0x1
#RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;
machine.mem32[stm.RCC_AHB3ENR] |= RCC_AHB3ENR_FSMCEN
#this shouldn't be needed in MP as MP should have already enabled all the clocks for all the GPIO ports
#RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN;
machine.mem32[stm.RCC_AHB1ENR] |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN
#FSMC_Bank1->BTCR[1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1;
machine.mem32[FSMC_Bank1_base + FSMC_BCR_bank1_offset] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1
#FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
machine.mem32[FSMC_Bank1_base + FSMC_BTR_bank1_offset] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Mon Jul 22, 2019 7:28 am
by DJShadow1966
Hello OutOfBots
Wish I had refreshed the post as I pretty much have typed up what you put. Again many thanks for all your help. So pretty much I now have :-
Code: Select all
import stm
import time
import machine
def FSMC_Init():
#constants of register
RCC_AHB3ENR_FSMCEN = 0x1 #bit to enable FSMC clock
RCC_AHB1ENR_GPIODEN = (0x1 << 3) #bit to enable D port clock
RCC_AHB1ENR_GPIOEEN = (0x1 << 4) #bit to enable E port clock
FSMC_Bank1_base = 0xA0000000 # FSMC registers base address
FSMC_BCR_bank1_offset = 0x0
FSMC_BTR_bank1_offset = 0x04
FSMC_BTR1_ADDSET_1 = 0x2
FSMC_BTR1_DATAST_1 = (0x02 << 8)
FSMC_BCR1_MWID_0 = (0x1 << 4)
FSMC_BCR1_WREN = (0x1 << 12)
FSMC_BCR1_MBKEN = 0x1
machine.mem32[stm.RCC_AHB3ENR] |= RCC_AHB3ENR_FSMCEN
machine.mem32[stm.RCC_AHB1ENR] |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN
machine.mem32[stm.GPIOD + stm.GPIO_MODER] |= 0b1100111110110011
machine.mem32[stm.GPIOE + stm.GPIO_MODER] |= 0b1111111110000000
machine.mem32[stm.GPIOD + stm.GPIO_OTYPER] &= 0b0011000001001100
machine.mem32[stm.GPIOE + stm.GPIO_OTYPER] &= 0b0000000001111111
machine.mem32[stm.GPIOD + stm.GPIO_OSPEEDR] |= (0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem32[stm.GPIOE + stm.GPIO_OSPEEDR] |= (0b11<<(2*7)) | (0b11<<(2*8)) | (0b11<<(2*9)) | (0b11<<(2*10)) | (0b11<<(2*11)) | (0b11<<(2*12)) | (0b11<<(2*13)) | (0b11<<(2*14)) | (0b11<<(2*15))
machine.mem32[stm.GPIOD + stm.GPIO_PUPDR] &= ((0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*6)) | (0b11<<(2*12)) | (0b11<<(2*13)))
machine.mem32[stm.GPIOE + stm.GPIO_PUPDR] &= ((0b11<<(2*0)) | (0b11<<(2*1)) | (0b11<<(2*2)) | (0b11<<(2*3)) | (0b11<<(2*4)) | (0b11<<(2*5)) | (0b11<<(2*6)))
machine.mem32[stm.GPIOD + stm.GPIO_AFR0] = (machine.mem32[stm.GPIOD + stm.GPIO_AFR0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7)
machine.mem32[stm.GPIOD + stm.GPIO_AFR1] = (machine.mem32[stm.GPIOD + stm.GPIO_AFR1] & (0b1111<<(4*(13-8)) | 0b1111<<(4*(12-8)))) | 0b1100<<(4*(8-8)) | 0b1100<<(4*(9-8)) | 0b1100<<(4*(10-8)) | 0b1100<<(4*(11-8)) | 0b1100<<(4*(14-8)) | 0b1100<<(4*(15-8))
machine.mem32[stm.GPIOE + stm.GPIO_AFR0] = (machine.mem32[stm.GPIOE + stm.GPIO_AFR0] & ~(0b1111<<7)) | 0b1100<<(4*7)
machine.mem32[stm.GPIOE + stm.GPIO_AFR1] = 0xCCCCCCCC
machine.mem32[FSMC_Bank1_base + FSMC_BCR_bank1_offset] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1
machine.mem32[FSMC_Bank1_base + FSMC_BTR_bank1_offset] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN
def TFT_Init():
BIT12 = const(1 << 12)
_BIT12 = const(0xFFFF ^ BIT12)
#hardware reset
machine.mem16[stm.GPIO_ODR] &= _BIT12
time.sleep_ms(250)
machine.mem16[stm.GPIO_ODR] |= BIT12
time.sleep_ms(120)
#SOFTWARE RESET
machine.mem8[LCD_REG] = 0x01
time.sleep_ms(1000)
#POWER CONTROL A
machine.mem8[LCD_REG] = 0xCB
machine.mem16[LCD_RAM] = 0x39
machine.mem16[LCD_RAM] = 0x2C
machine.mem16[LCD_RAM] = 0x00
machine.mem16[LCD_RAM] = 0x34
machine.mem16[LCD_RAM] = 0x02
#DRIVER TIMING CONTROL A
machine.mem8[LCD_REG] = 0xE8
machine.mem16[LCD_RAM] = 0x85
machine.mem16[LCD_RAM] = 0x00
machine.mem16[LCD_RAM] = 0x78
#DRIVER TIMING CONTROL B
machine.mem8[LCD_REG] = 0xEA
machine.mem16[LCD_RAM] = 0x00
machine.mem16[LCD_RAM] = 0x00
#POWER ON SEQUENCE CONTROL
machine.mem8[LCD_REG] = 0xED
machine.mem16[LCD_RAM] = 0x64
machine.mem16[LCD_RAM] = 0x03
machine.mem16[LCD_RAM] = 0x12
machine.mem16[LCD_RAM] = 0x81
#PUMP RATIO CONTROL
machine.mem8[LCD_REG] = 0xF7
machine.mem16[LCD_RAM] = 0x20
#POWER CONTROL,VRH[5:0]
machine.mem8[LCD_REG] = 0xC0
machine.mem16[LCD_RAM] = 0x23
#POWER CONTROL,SAP[2:0]BT[3:0]
machine.mem8[LCD_REG] = 0xC1
machine.mem16[LCD_RAM] = 0x10
#VCM CONTROL
machine.mem8[LCD_REG] = 0xC5
machine.mem16[LCD_RAM] = 0x3E
machine.mem16[LCD_RAM] = 0x28
#VCM CONTROL 2
machine.mem8[LCD_REG] = 0xC7
machine.mem16[LCD_RAM] = 0x86
#MEMORY ACCESS CONTROL
machine.mem8[LCD_REG] = 0x36
machine.mem16[LCD_RAM] = 0x48
#PIXEL FORMAT
machine.mem8[LCD_REG] = 0x3A
machine.mem16[LCD_RAM] = 0x55
#FRAME RATIO CONTROL, STANDARD RGB COLOR
machine.mem8[LCD_REG] = 0xB1
machine.mem16[LCD_RAM] = 0x00
machine.mem16[LCD_RAM] = 0x18
#DISPLAY FUNCTION CONTROL
machine.mem8[LCD_REG] = 0xB6
machine.mem16[LCD_RAM] = 0x08
machine.mem16[LCD_RAM] = 0x82
machine.mem16[LCD_RAM] = 0x27
#3GAMMA FUNCTION DISABLE
machine.mem8[LCD_REG] = 0xF2
machine.mem16[LCD_RAM] = 0x00
#GAMMA CURVE SELECTED
machine.mem8[LCD_REG] = 0x26
machine.mem16[LCD_RAM] = 0x01
#POSITIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE0
machine.mem16[LCD_RAM] = 0x0F
machine.mem16[LCD_RAM] = 0x31
machine.mem16[LCD_RAM] = 0x2B
machine.mem16[LCD_RAM] = 0x0C
machine.mem16[LCD_RAM] = 0x0E
machine.mem16[LCD_RAM] = 0x08
machine.mem16[LCD_RAM] = 0x4E
machine.mem16[LCD_RAM] = 0xF1
machine.mem16[LCD_RAM] = 0x37
machine.mem16[LCD_RAM] = 0x07
machine.mem16[LCD_RAM] = 0x10
machine.mem16[LCD_RAM] = 0x03
machine.mem16[LCD_RAM] = 0x0E
machine.mem16[LCD_RAM] = 0x09
machine.mem16[LCD_RAM] = 0x00
#NEGATIVE GAMMA CORRECTION
machine.mem8[LCD_REG] = 0xE1
machine.mem16[LCD_RAM] = 0x00
machine.mem16[LCD_RAM] = 0x0E
machine.mem16[LCD_RAM] = 0x14
machine.mem16[LCD_RAM] = 0x03
machine.mem16[LCD_RAM] = 0x11
machine.mem16[LCD_RAM] = 0x07
machine.mem16[LCD_RAM] = 0x31
machine.mem16[LCD_RAM] = 0xC1
machine.mem16[LCD_RAM] = 0x48
machine.mem16[LCD_RAM] = 0x08
machine.mem16[LCD_RAM] = 0x0F
machine.mem16[LCD_RAM] = 0x0C
machine.mem16[LCD_RAM] = 0x31
machine.mem16[LCD_RAM] = 0x36
machine.mem16[LCD_RAM] = 0x0F
#EXIT SLEEP
machine.mem8[LCD_REG] = 0x11
time.sleep_ms(120)
#TURN ON DISPLAY
machine.mem8[LCD_REG] = 0x29
#display inversion
#machine.mem8[LCD_REG] = 0x21
#setup Memory Access Control
machine.mem8[LCD_REG] = 0x36
machine.mem16[LCD_RAM] = 0b00111111
def ILI9341_Set_Address(X1, Y1, X2, Y2):
#set X min and max
machine.mem8[LCD_REG] = 0x2A
machine.mem16[LCD_RAM] = X1>>8
machine.mem16[LCD_RAM] = X1
machine.mem16[LCD_RAM] = X2>>8
machine.mem16[LCD_RAM] = X2
#set y min and max
machine.mem8[LCD_REG] = 0x2B
machine.mem16[LCD_RAM] = Y1>>8
machine.mem16[LCD_RAM] = Y1
machine.mem16[LCD_RAM] = Y2>>8
machine.mem16[LCD_RAM] = Y2
#write data command
machine.mem8[LCD_REG] = 0x2C
def draw_pixel(X, Y, colour):
ILI9341_Set_Address(X, Y, X, Y)
machine.mem16[LCD_RAM] = colour
LCD_REG = const(0x60000000)
LCD_RAM = const(0x60080000)
Regards Mike
Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards
Posted: Mon Jul 22, 2019 8:17 am
by Roberthh
Using the mem_xx() functions is very slow. For initialization, that's fine. But for other operations like setting coordinates or data transfer using native code and direct pointers is way faster. I used that for my SSD1963 driver (
https://github.com/robert-hh/SSD1963-TF ... or-PyBoard), which uses 8 bit parallel data transfers. The file TFT_io.py contains the functions for accessing the memory, both native and assembly code. Native code only takes twice the time of assembly code, but is much easier to write and maintain, since the control structures of Python are available.