MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Sniper
Posts: 21
Joined: Mon Jan 06, 2020 2:32 pm

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by Sniper » Fri Feb 14, 2020 2:58 am

Here are the pin diagram/infographic layout from my Google Drive hope it will come to any use!

https://drive.google.com/drive/folders/ ... sp=sharing

User avatar
mcauser
Posts: 507
Joined: Mon Jun 15, 2015 8:03 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by mcauser » Fri Feb 14, 2020 3:22 am

Hi @Sniper.
Is this necessary in the code? import machine and import time, import Pin?
Unless your boot.py or main.py imports machine, you'll need to do it before you can use it. Otherwise you'll get a NameError.

import time lets you use time.sleep(). Without it, time won't exist (in the variable sense). Again, if it's in your boot or main.py, it's already imported. You can see what is imported by running dir().

You don't need to import Pin. It does not exist. Pin is a class inside machine. You get it when you import machine (all of machine) and is accessible as machine.Pin.

An alternate syntax which lets you import some of machine is: from machine import Pin, I2C.
If you use this syntax, machine.Pin doesn't exist. It's just Pin, so you'll need to remove the "machine." prefixes below.

Code: Select all

import machine
import time

# relay 1
p = machine.Pin.cpu.PE0
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

# relay 2
p = machine.Pin.cpu.PE1
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)
If you change import machine to from machine import Pin, you'll need to replace all machine.Pin occurrences below with just Pin.

Same goes for time.sleep. If you from time import sleep, then you can just call sleep(2) below.

Sniper
Posts: 21
Joined: Mon Jan 06, 2020 2:32 pm

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by Sniper » Fri Feb 14, 2020 1:29 pm

mcauser wrote:
Fri Feb 14, 2020 3:22 am
Hi @Sniper.
Is this necessary in the code? import machine and import time, import Pin?
Unless your boot.py or main.py imports machine, you'll need to do it before you can use it. Otherwise you'll get a NameError.

import time lets you use time.sleep(). Without it, time won't exist (in the variable sense). Again, if it's in your boot or main.py, it's already imported. You can see what is imported by running dir().

You don't need to import Pin. It does not exist. Pin is a class inside machine. You get it when you import machine (all of machine) and is accessible as machine.Pin.

An alternate syntax which lets you import some of machine is: from machine import Pin, I2C.
If you use this syntax, machine.Pin doesn't exist. It's just Pin, so you'll need to remove the "machine." prefixes below.

Code: Select all

import machine
import time

# relay 1
p = machine.Pin.cpu.PE0
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

# relay 2
p = machine.Pin.cpu.PE1
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)
If you change import machine to from machine import Pin, you'll need to replace all machine.Pin occurrences below with just Pin.

Same goes for time.sleep. If you from time import sleep, then you can just call sleep(2) below.
I still can get the code run, nothing happens.
this is what is in my boot.py

Code: Select all

# boot.py -- run on boot-up
# can run arbitrary Python, but best to keep it minimal

import machine
import pyb
pyb.country('US') # ISO 3166-1 Alpha-2 code, eg US, GB, DE, AU
#pyb.main('main.py') # main script to run after this one
#pyb.usb_mode('VCP+MSC') # act as a serial and a storage device
#pyb.usb_mode('VCP+HID') # act as a serial device and a mouse
and this is the code for 8 channel relay. but it wont run as expected.

Code: Select all

# 8 Channel Relay Module

import machine
import time

#Relay Nr.1

p = machine.Pin.cpu.PE0
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

# relay 2

p = machine.Pin.cpu.PE1
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

#Relay Nr.3

p = machine.Pin.cpu.PE2
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

#Relay Nr.4

p = machine.Pin.cpu.PE3
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

#Relay Nr.5

p = machine.Pin.cpu.PE4
p.init(mode=machine.Pin.OUT)
p.value(0)
time.sleep(2)
p.value(1)

#End of the code!

Sniper
Posts: 21
Joined: Mon Jan 06, 2020 2:32 pm

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by Sniper » Fri Feb 14, 2020 6:38 pm

Can you please tell where and how a newbie like me can read and learn about how to program this boards for absolute beginners.

holberg
Posts: 8
Joined: Mon Apr 20, 2020 9:01 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by holberg » Mon Apr 20, 2020 4:37 pm

OutoftheBOTS_ wrote:
Sun Jul 21, 2019 10:41 pm
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
Hello OutoftheBOTS,
how would the FSMC looks like, when I want to try the build in header ? (for PD13 insteed of PD11)
tnank you
regards
Holberg

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by OutoftheBOTS_ » Tue Apr 21, 2020 6:16 am

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.
Ok it has been long time since I worked this out so will try to remember it. FSMC hardware peripheral can set the 16 address pins and the 16 data pins all at once so that it can send 16 bits of data to an address in RAM all in 1 cycle. With the TFT we only use 1 of the address pins and we use it to operate the RS/DC (register select AKA data/command) pin. This tells the TFT whether we want to write the 16 bits of data to the Graphics RAM or to the control registers. So if the RS/DC pins is LOW the TFT writes to the control registers and if it is HIGH it writes it to the GRAM. I had

I had the RS/DC pin connected to FSMC A16 (address pin 16, physical CPU pin PD11) so when I write to 0x60020000 it sends A16 HIGH. If you use a different pin like FSMC A18 then you will need to use a different address, you will also have to set up that different pin as a AF FSMC pin too

Code: Select all

#define LCD_REG      (*((volatile unsigned short *) 0x60000000))
#define LCD_RAM      (*((volatile unsigned short *) 0x60020000))

Code: Select all

//set other pins to AF12 i.e as FSMC pins
	GPIOD->AFR[0] = (GPIOD->AFR[0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7);
	GPIOD->AFR[1] = (GPIOD->AFR[1] & (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));
	GPIOE->AFR[0] = (GPIOE->AFR[0] & ~(0b1111<<7)) | 0b1100<<(4*7);
	GPIOE->AFR[1] = 0xCCCCCCCC;

holberg
Posts: 8
Joined: Mon Apr 20, 2020 9:01 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by holberg » Tue Apr 21, 2020 8:59 am

OutoftheBOTS_ wrote:
Tue Apr 21, 2020 6:16 am
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.
Ok it has been long time since I worked this out so will try to remember it. FSMC hardware peripheral can set the 16 address pins and the 16 data pins all at once so that it can send 16 bits of data to an address in RAM all in 1 cycle. With the TFT we only use 1 of the address pins and we use it to operate the RS/DC (register select AKA data/command) pin. This tells the TFT whether we want to write the 16 bits of data to the Graphics RAM or to the control registers. So if the RS/DC pins is LOW the TFT writes to the control registers and if it is HIGH it writes it to the GRAM. I had

I had the RS/DC pin connected to FSMC A16 (address pin 16, physical CPU pin PD11) so when I write to 0x60020000 it sends A16 HIGH. If you use a different pin like FSMC A18 then you will need to use a different address, you will also have to set up that different pin as a AF FSMC pin too

Code: Select all

#define LCD_REG      (*((volatile unsigned short *) 0x60000000))
#define LCD_RAM      (*((volatile unsigned short *) 0x60020000))

Code: Select all

//set other pins to AF12 i.e as FSMC pins
	GPIOD->AFR[0] = (GPIOD->AFR[0] & (0b1111<<(4*2) | 0b1111<<(4*3) | 0b1111<<(4*6))) | 0b1100<<(4*0) | 0b1100<<(4*1) | 0b1100<<(4*4) | 0b1100<<(4*5) | 0b1100<<(4*7);
	GPIOD->AFR[1] = (GPIOD->AFR[1] & (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));
	GPIOE->AFR[0] = (GPIOE->AFR[0] & ~(0b1111<<7)) | 0b1100<<(4*7);
	GPIOE->AFR[1] = 0xCCCCCCCC;
Thank you for the answer,
ok, I'm right this is the defintion for pin 2 0b1111<<(4*2) and this also for pin 13 0b1111<<(4*(13-8)

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by OutoftheBOTS_ » Tue Apr 21, 2020 11:43 pm

I wrote the code quite a while ago so without sitting down and reading the reference manual and looking at the code to remember what I did I couldn't be certain but that looks about right :)

holberg
Posts: 8
Joined: Mon Apr 20, 2020 9:01 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by holberg » Thu Apr 23, 2020 9:51 am

OutoftheBOTS_ wrote:
Tue Apr 21, 2020 11:43 pm
I wrote the code quite a while ago so without sitting down and reading the reference manual and looking at the code to remember what I did I couldn't be certain but that looks about right :)
I got it running. ILIDriver now in micropython.

But when I want to implement a ILI9341 grafic class, I' run out of RAM. If I check the availabel Memory

MicroPython v1.12-387-g1b1ceb67b on 2020-04-19; MCUDEV STM32F407VE with STM32F407VE
Type "help()" for more information.
>>> import gc
>>> gc.collect()
>>> gc.mem_free()
33280

its not this much, any Idea ?

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: MCUDev Black STM32F407VET6 + STM32F407ZET6 dev boards

Post by OutoftheBOTS_ » Fri Apr 24, 2020 8:26 am

holberg wrote:
Thu Apr 23, 2020 9:51 am
OutoftheBOTS_ wrote:
Tue Apr 21, 2020 11:43 pm
I wrote the code quite a while ago so without sitting down and reading the reference manual and looking at the code to remember what I did I couldn't be certain but that looks about right :)
I got it running. ILIDriver now in micropython.

But when I want to implement a ILI9341 grafic class, I' run out of RAM. If I check the availabel Memory

MicroPython v1.12-387-g1b1ceb67b on 2020-04-19; MCUDEV STM32F407VE with STM32F407VE
Type "help()" for more information.
>>> import gc
>>> gc.collect()
>>> gc.mem_free()
33280

its not this much, any Idea ?
Low RAM is the big factor in using this MCU for graphic. The work around is that you have very fast access to the TFT RAM so you need to program in a way that makes use of the TFT RAM and only having super minimal stuff in MCU RAM

Post Reply