MCUFRIEND_kbv
MCUFRIEND_kbv copied to clipboard
Changing the pinout is very unfriendly
Hello,
I would like to try the 2.4 display (0x0154) with a multichannel oscilloscope project, which uses the STM32. On the Arduino Mega2560 the dispay works well. But at the moment, I am not able to adapt the display pins, I made some changes to the file "mcufriend_shield.h", but it was not enough to work, could somebody tell me what is the most correct way to change the pinout for this below:
#define TFT_DATA GPIOB // Port data bits D0..D7:
//Control pins |RD |WR |RS |CS |RST| #define TFT_RD PB10 #define TFT_WR PC15 #define TFT_RS PC14 #define TFT_CS PC13 #define TFT_RST PB11
The project originally uses ILI9341, and I can not change the layout of the board: https://github.com/ardyesp/DLO-138
Schematic (better resolution): https://jyetech.com/Products/LcdScope/UserManual_138_new.pdf
Original file "mcufriend_shield.h":
#elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8) #warning Uno Shield on BLUEPILL #define RD_PORT GPIOB //#define RD_PIN 5 #define RD_PIN 0 //hardware mod to Adapter. Allows use of PB5 for SD Card #define WR_PORT GPIOB #define WR_PIN 6 #define CD_PORT GPIOB #define CD_PIN 7 #define CS_PORT GPIOB #define CS_PIN 8 #define RESET_PORT GPIOB #define RESET_PIN 9
// configure macros for the data pins #define write_8(d) { GPIOA->REGS(BSRR) = 0x00FF << 16; GPIOA->REGS(BSRR) = (d) & 0xFF; } #define read_8() (GPIOA->REGS(IDR) & 0xFF) // PA7 ..PA0 #define setWriteDir() {GP_OUT(GPIOA, CRL, 0xFFFFFFFF); } #define setReadDir() {GP_INP(GPIOA, CRL, 0xFFFFFFFF); }
Modifield:
#elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8) #warning Uno Shield on BLUEPILL #define RD_PORT GPIOB //#define RD_PIN 5 #define RD_PIN 10 //hardware mod to Adapter. Allows use of PB5 for SD Card #define WR_PORT GPIOC #define WR_PIN 15 #define CD_PORT GPIOC #define CD_PIN 14 #define CS_PORT GPIOC #define CS_PIN 13 #define RESET_PORT GPIOB #define RESET_PIN 11
// configure macros for the data pins #define write_8(d) { GPIOB->REGS(BSRR) = 0x00FF << 16; GPIOB->REGS(BSRR) = (d) & 0xFF; } #define read_8() (GPIOB->REGS(IDR) & 0xFF) // PA7 ..PA0 #define setWriteDir() {GP_OUT(GPIOB, CRL, 0xFFFFFFFF); } #define setReadDir() {GP_INP(GPIOB, CRL, 0xFFFFFFFF); }
Thank you!
God invented Shields. You plug a Shield into an Arduino or NUCLEO. All the wiring is known. The display works.
If you want to use a BluePill, wire everything according to the "BluePill Adapter" published on stm32duino Forum.
There are several SPECIALs for different BluePill wiring. If you are too stubborn to use the "Adapter" wiring, choose one of the SPECIALs. SPECIALs go in the utility/mcufriend_special.h file
If you are even more stubborn, wire up your display in your own custom way. Edit the #defines in LCD_ID_readreg sketch. Make sure that it reads the registers correctly. Post your verified #defines. And I will post a SPECIAL especially for you.
I have no intention of writing a SPECIAL from your schematic. I will only do it when I see your verified #defines
David.
Yes I agree with you, God invented, and each man makes a point of using a different configuration for each piece.
I'll check the files, thanks for the support!
I ran the example "LCD_ID_readreg.ino", but the result of Mega2560 was different from STM32.
With the help of an oscilloscope, I noticed that pins PB0 and PB1 do not work during the execution of the example "LCD_ID_readreg.ino".
I did a test to "blink" the pins PB0 and PB1. They worked correctly.
#define LCD_RST PB11
#define LCD_CS PC13
#define LCD_RS PC14
#define LCD_WR PC15
#define LCD_RD PB10
#define LCD_D0 PB0
#define LCD_D1 PB1
#define LCD_D2 PB2
#define LCD_D3 PB3
#define LCD_D4 PB4
#define LCD_D5 PB5
#define LCD_D6 PB6
#define LCD_D7 PB7
Sorry i made a mistake
I reviewed the links and realized that I gave the wrong reference, it is not the PB0 and PB1 pin that is not working.
The pin that is not working is the PB3.
It also did not work with my "blink" test, I will check the reason the PB3 pin does not work.
Your #defines match the schematic. There is no point in running a blinky that verifies only two pins.
You must verify the full set of defines works with LCD_ID_readreg. Your schematic shows TX1, RX1 on PA9, PA10 which will work 100% with a UART-USB dongle. If you are using the weird Maple Core the "USB" Serial may or may not work.
Surely your DSO138 scope kit comes with its own ILI9341 display and software. The kits seem incredibly cheap. The performance will probably be mediocre. A 1Msps means that you can only really see 20kHz or so. I do not have a modern scope. Only a 10MHz analog scope that I bought in the 1970s and seldom used.
David.
Working now!
I had to disable the JTAG of this PB3 pin:
I added the instruction below at the beginning of the subroutine "setup"
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
Source: http://www.stm32duino.com/viewtopic.php?t=1130#p13918
STM32:
Read Registers on MCUFRIEND UNO shield controllers either read as single 16-bit e.g. the ID is at readReg(0) or as a sequence of 8-bit values in special locations (first is dummy)
reg(0x0000) 01 54 ID: ILI9320, ILI9325, ILI9335, ... reg(0x0004) 00 00 00 00 Manufacturer ID reg(0x0009) 00 1E 00 00 00 Status Register reg(0x000A) 00 00 Get Power Mode reg(0x000C) 00 00 Get Pixel Format reg(0x0061) 00 00 RDID1 HX8347-G reg(0x0062) 00 00 RDID2 HX8347-G reg(0x0063) 00 00 RDID3 HX8347-G reg(0x0064) 00 00 RDID1 HX8347-A reg(0x0065) 00 00 RDID2 HX8347-A reg(0x0066) 00 00 RDID3 HX8347-A reg(0x0067) 00 00 RDID Himax HX8347-A reg(0x0070) 00 00 Panel Himax HX8347-A reg(0x00A1) 00 00 00 00 00 RD_DDB SSD1963 reg(0x00B0) 00 00 RGB Interface Signal Control reg(0x00B4) 00 00 Inversion Control reg(0x00B6) 00 00 00 00 00 Display Control reg(0x00B7) 00 00 Entry Mode Set reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B reg(0x00C0) 00 00 00 00 00 00 00 00 00 Panel Control reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA reg(0x00CC) 00 00 Panel Control reg(0x00D0) 00 00 00 Power Control reg(0x00D2) 00 00 00 00 00 NVM Read reg(0x00D3) 00 00 00 00 ILI9341, ILI9488 reg(0x00D4) 00 00 00 00 Novatek ID reg(0x00DA) 00 00 RDID1 reg(0x00DB) 00 00 RDID2 reg(0x00DC) 00 00 RDID3 reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N reg(0x00EF) 00 00 00 00 00 00 ILI9327 reg(0x00F2) 00 00 00 00 00 00 00 00 00 00 00 00 Adjust Control 2 reg(0x00F6) 00 00 00 00 Interface Control
Mega2560:
Read Registers on MCUFRIEND UNO shield controllers either read as single 16-bit e.g. the ID is at readReg(0) or as a sequence of 8-bit values in special locations (first is dummy)
reg(0x0000) 01 54 ID: ILI9320, ILI9325, ILI9335, ... reg(0x0004) 00 00 00 00 Manufacturer ID reg(0x0009) 00 1E 00 00 00 Status Register reg(0x000A) 00 00 Get Power Mode reg(0x000C) 00 00 Get Pixel Format reg(0x0061) 00 00 RDID1 HX8347-G reg(0x0062) 00 00 RDID2 HX8347-G reg(0x0063) 00 00 RDID3 HX8347-G reg(0x0064) 00 00 RDID1 HX8347-A reg(0x0065) 00 00 RDID2 HX8347-A reg(0x0066) 00 00 RDID3 HX8347-A reg(0x0067) 00 00 RDID Himax HX8347-A reg(0x0070) 00 00 Panel Himax HX8347-A reg(0x00A1) 00 00 00 00 00 RD_DDB SSD1963 reg(0x00B0) 00 00 RGB Interface Signal Control reg(0x00B4) 00 00 Inversion Control reg(0x00B6) 00 00 00 00 00 Display Control reg(0x00B7) 00 00 Entry Mode Set reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B reg(0x00C0) 00 00 00 00 00 00 00 00 00 Panel Control reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA reg(0x00CC) 00 00 Panel Control reg(0x00D0) 00 00 00 Power Control reg(0x00D2) 00 00 00 00 00 NVM Read reg(0x00D3) 00 00 00 00 ILI9341, ILI9488 reg(0x00D4) 00 00 00 00 Novatek ID reg(0x00DA) 00 00 RDID1 reg(0x00DB) 00 00 RDID2 reg(0x00DC) 00 00 RDID3 reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N reg(0x00EF) 00 00 00 00 00 00 ILI9327 reg(0x00F2) 00 00 00 00 00 00 00 00 00 00 00 00 Adjust Control 2 reg(0x00F6) 00 00 00 00 Interface Control
Yes, the oscilloscope with STM32F103C8T6 has a very small bandwidth,
But I work with repairing power supply, and I need to monitor two 30ms signals, so this need can be met satisfactorily with this circuit.
My goal is to do a test JIG.
I bought a DSO-150 (200kHz band) but unfortunately this model has only 1 channel.
Success at last !!! PB3 is not used by SWD but PB4 certainly is.
I am taking my dog out. I will post a SPECIAL for you when I get back.
David.
Many thanks for the attention, David!
I will comment there on the project about this possibility of display,
Surely others will be able to test this display in this project!
#define USE_SPECIAL in shield.h #define (USE_RTEK1000_BLUEPILL in special.h add the following block to special.h
#elif defined(USE_RTEK1000_BLUEPILL) && (defined(__STM32F1__) || defined(STM32F103xB)) // MAPLECORE or STM32CORE
#warning USE_RTEK1000_BLUEPILL
#if defined(ARDUINO_NUCLEO_F103C8) //regular CMSIS libraries
#define REGS(x) x
#define GPIO_INIT() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#else //weird Maple libraries
#define REGS(x) regs->x
#endif
#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444)
#define PIN_OUTPUT(port, pin) {\
if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
}
#define PIN_INPUT(port, pin) { \
if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
}
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))
#define RD_PORT GPIOB
#define RD_PIN 10
#define WR_PORT GPIOC
#define WR_PIN 15
#define CD_PORT GPIOC
#define CD_PIN 14
#define CS_PORT GPIOC
#define CS_PIN 13
#define RESET_PORT GPIOB
#define RESET_PIN 11
// configure macros for the data pins
#define write_8(d) { GPIOB->REGS(BSRR) = 0x00FF << 16; GPIOB->REGS(BSRR) = ((d) << 0) & 0x00FF; }
#define read_8() ((GPIOB->REGS(IDR) & 0x00FF) >> 0)
// PB7..PB0
#define setWriteDir() {GP_OUT(GPIOB, CRL, 0xFFFFFFFF); }
#define setReadDir() {GP_INP(GPIOB, CRL, 0xFFFFFFFF); }
#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
I still don't understand your project. A DSO138 kit will have all the components. Trying to build a scope with a BluePill and Mcufriend shield sounds like a lot of hard work.
David.
Edit. Your original "special" looks exactly the same as mine. Except that your comments claim the data ports on PA0..PA7 when the code is for PB0..PB7
Yes! It works! But only if I disable the debug on PB3 pin.
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
So, in the end, it was just the problem of the debug function.
Sorry for bothering you.
I noticed that the backlight of the display was blinking, when monitoring the voltage (with the DSO150) I could see that the 3.3V pin of the display was oscillating, so I connected this pin to the 3.3V pin and it stopped oscillating the backlight , is very beautiful, much faster than the Mega2560.
Thank you! (By patience too)
Yes, the DSO138 kit is already complete (for 1 channel), you're right, and it really does not make sense.
The big problem is access to the kit, where I am not so simple and easy to get, I have to pay several times the value in dollars, sometimes it comes to cost 6x.
So, since I was with the STM32 and the mcufriend display in the drawer, it made some sense for me to try to use them together!
Thank you!
If anyone needs this adaptation, the files already configured are attached.
Thank you!
mcufriend_shield.zip mcufriend_special.zip
Shield:
Image source: http://domoticx.com/wp-content/uploads/2015/03/MCUFriend-2.4-inch-LCD-Shield-S6D0154-driver-0x0154-onderkant.jpg
Hello. Sorry for my english. Could you help me . I changed the display to DSO 138, and now instead of ili9341 it became 0x9595. I am uploading the DLO138 mcufriend project to the DSO 138 board. I use define support hx8347d But nothing happens. Always white screen .... Thank you.
when you add afio_cfg_debug_ports(AFIO_DEBUG_NONE); on bluepill readID() can't found ID always white screen ....I edit mcufriend and now it work
когда вы добавляете afio_cfg_debug_ports (AFIO_DEBUG_NONE); on bluepill readID () не может найти идентификатор всегда белого экрана .... Я редактирую mcufriend, и теперь он работает
Please tell me, what to edit in mcufriend?
i will upload soon, i design pcb DSO 138 with Protues 8 again but i finish yet. i upload when i finish or somebody share file pcb DSO 138. Thanks
I do not understand a hobbyist making their own pcb. Ready-made pcb is cheap. I do not understand an enthusiast developing any scope software with an obsolete STM32F103.
Yes, it might be worth developing an improved performance commercial kit with a Cortex-M4.
I am not an oscilloscope person. I do everything with Logic Analyser and SWD/JTAG debugger. However I have often thought of buying a mid-range Rigol or Hantek scope. My 40-year old 20MHz Analog scope has only been used about 5 times in the last 30 years.
A 200kHz project seems a little pointless. Everyone has their personal opinions! I don't mind helping with software but ONLY if the hardware is on a professionally made pcb with proper socket / soldered connections to the TFT.
David.
rtek1000 - Thanks for upload files. But i'm confused. Can anyone tell me what is final wiring for use this two attached files (shield and special.h)
#define RD_PORT GPIOB #define RD_PIN 10 #define WR_PORT GPIOC #define WR_PIN 15 #define CD_PORT GPIOC #define CD_PIN 14 #define CS_PORT GPIOC #define CS_PIN 13 #define RESET_PORT GPIOB #define RESET_PIN 11
Is that correct? What about LCD_D0 to LCD_D7 ?
Best regards
I can not see any attached files.
Surely it is easier to just use the default wiring for BLUEPILL in shield.h. Then you don't have to worry about Specials.
If you have a compelling reason to use special wiring, test it with LCD_ID_readreg sketch. Then post your #defines. Preferably on Arduino.cc Forum. But Github or stm32duino Forum is ok.
I do not mind writing the SPECIAL for you but only if you have verified your wiring first.
David.
prenticedavid - thank You for Your answer.
I found in mcufriend_shield.h:
#define RD_PORT GPIOB //#define RD_PIN 5 #define RD_PIN 0 //hardware mod to Adapter. Allows use of PB5 for SD Card #define WR_PORT GPIOB #define WR_PIN 6 #define CD_PORT GPIOB #define CD_PIN 7 #define CS_PORT GPIOB #define CS_PIN 8 #define RESET_PORT GPIOB #define RESET_PIN 9
and this is clear: RD - PB0 WR - PB6 CD - PB7 CS - PB8 RESET - PB9
but what about LCD_D0 to LCD_D7 ? I was trying that way: PA0 - LCD_D0 .... to .... PA7 - LCD_D7 but it doesn't work (blank screeen).
Can anyone help me and write down correct default connection with BluePill? Best regards
Yes, data bus is on PA0..PA7. Wire it up. Run LCD_ID_readreg sketch. #define LCD_D0 PA0 etc
In an ideal world you plug a a ready made shield into Uno, Zero, Due, ..., Nucleo, ...
No need for any SPECIAL at all. You just have to make sure that all the male pins mate with the corresponding header sockets.
David.
LCD_ID_readreg gives me: `Read Registers on MCUFRIEND UNO shield controllers either read as single 16-bit e.g. the ID is at readReg(0) or as a sequence of 8-bit values in special locations (first is dummy)
reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ... reg(0x0004) 00 54 80 66 Manufacturer ID reg(0x0009) 01 01 01 01 01 Status Register reg(0x000A) 00 08 Get Power Mode reg(0x000C) 00 06 Get Pixel Format reg(0x0061) 01 01 RDID1 HX8347-G reg(0x0062) 00 00 RDID2 HX8347-G reg(0x0063) 01 01 RDID3 HX8347-G reg(0x0064) 00 00 RDID1 HX8347-A reg(0x0065) 01 01 RDID2 HX8347-A reg(0x0066) 00 00 RDID3 HX8347-A reg(0x0067) 01 01 RDID Himax HX8347-A reg(0x0070) 00 00 Panel Himax HX8347-A reg(0x00A1) 01 01 01 01 01 RD_DDB SSD1963 reg(0x00B0) 00 00 RGB Interface Signal Control reg(0x00B4) 00 02 Inversion Control reg(0x00B6) 00 06 06 06 06 Display Control reg(0x00B7) 01 07 Entry Mode Set reg(0x00BF) 01 01 01 01 01 01 ILI9481, HX8357-B reg(0x00C0) 00 0E 0E 0E 0E 0E 0E 0E 0E Panel Control reg(0x00C8) 00 B0 B0 B0 B0 B0 B0 B0 B0 B0 B0 B0 B0 GAMMA reg(0x00CC) 00 02 Panel Control reg(0x00D0) 00 00 00 Power Control reg(0x00D2) 00 00 94 88 88 NVM Read reg(0x00D3) 01 01 95 89 ILI9341, ILI9488 reg(0x00D4) 00 96 00 00 Novatek ID reg(0x00DA) 00 80 RDID1 reg(0x00DB) 01 81 RDID2 reg(0x00DC) 00 66 RDID3 reg(0x00E0) 00 00 06 0C 04 12 08 36 AA 46 08 10 0C 1A 1E 0E GAMMA-P reg(0x00E1) 01 01 21 23 05 11 07 37 57 49 05 0D 0B 33 37 0F GAMMA-N reg(0x00EF) 01 01 01 01 01 01 ILI9327 reg(0x00F2) 00 0A 20 00 AA 12 12 12 12 12 12 12 Adjust Control 2 reg(0x00F6) 00 A8 50 2C Interface Control `
But when I upload any sketch from examples ie diagnose_TFT_support screen stays white.
This display (3.95 TFT LCD mcufriend) works with NUCLEO-F103RB nad Arduino UNO, but BLUE PILL - no luck... any ideas? Best regards
Hello,
Let me try to clarify the basics,
The stm32, has a way of operating the inputs and outputs well differentiated (I worked with PIC, I found it very complicated)
See this part:
// configure macros for the data pins
#define write_8(d) { GPIOB->REGS(BSRR) = 0x00FF << 16; GPIOB->REGS(BSRR) = ((d) << 0) & 0x00FF; }
#define read_8() ((GPIOB->REGS(IDR) & 0x00FF) >> 0)
// PB7..PB0
#define setWriteDir() {GP_OUT(GPIOB, CRL, 0xFFFFFFFF); }
#define setReadDir() {GP_INP(GPIOB, CRL, 0xFFFFFFFF); }
Look at these terms:
- BSRR
- IDR
- CRL
Now access the user manual: https://www.st.com/en/microcontrollers/stm32f103.html?querycriteria=productId=LN1565
Click the Resources tab, and locate: Reference Manual: (1), click, and you should open another page: https://www.st.com/content/st_com/en/support/resources/resource-selector.html?querycriteria=productId=LN1565$$resourceCategory=technical_literature$$resourceType=reference_manual
Download the file: RM0008
Open the PDF file, find: 9.1 GPIO functional description: Read this, and understand:
-
"Each of the general-purpose I / O ports has:"
-
two 32-bit configuration registers (GPIOx_CRL, GPIOx_CRH),
--> Note the abbreviations: [CRL: (C)onfiguration (R)egister {L}ow] [CRH: (C)onfiguration (R)egister (H)igh]
- two 32-bit data registers (GPIOx_IDR, GPIOx_ODR),
- the 32-bit set / reset register (GPIOx_BSRR),
- the 16-bit reset register (GPIOx_BRR) and
- the 32-bit locking register (GPIOx_LCKR).
Now understand the code:
#define write_8(d) { GPIOB->REGS(BSRR) = 0x00FF << 16; GPIOB->REGS(BSRR) = ((d) << 0) & 0x00FF;
"GPIOB->REGS(BSRR) = 0x00FF << 16"
"0x00FF << 16" means: 0b0000000011111111 << 16 0b0000000011111111 << 16 that means: 0b1111111100000000
So, the register (set / reset register) BSRR will receive the value 0b1111111100000000
After this preparation, the value of the pins corresponding to the connection with the shield will be set "GPIOB->REGS(BSRR) = ((d) << 0) & 0x00FF"
The register BSRR will receive the value that is in the variable "d"
For the other register everything happens in a similar way.
As I said at the beginning, it is complicated to understand this logic of clearing the registry before setting the value, and also think that most people learn to program at high level, and on 8-bit controllers, but are not instructed to look for the component manual.
I hope this helps someone who is starting.
A tip: enjoy and read all the files the manufacturer provides (Click the Resources tab): https://www.st.com/en/microcontrollers/stm32f103.html?querycriteria=productId=LN1565
I'm sorry, but that means I have to make some modifications in library... So it doesn't work "out of box" with Blue Pill... Ok, that is to much for me. I give up. Thanks for help.
Your readreg is "almost" ok. It looks like you have an ILI9488 controller
reg(0x0004) 00 54 80 66 Manufacturer ID
...
reg(0x00D3) 01 01 95 89 ILI9341, ILI9488
...
reg(0x00DA) 00 80 RDID1
reg(0x00DB) 01 81 RDID2
reg(0x00DC) 00 66 RDID3
I would expect to see:
reg(0x0004) 00 54 80 66 Manufacturer ID
reg(0x00D3) 00 00 94 88 RDID4
reg(0x00DA) 00 54 RDID1
reg(0x00DB) 00 80 RDID2
reg(0x00DC) 00 66 RDID3
So there is something wrong with your LCD_D0 pin. I suspect that your wiring is done with clothes pegs. You can try forcing tft.begin(0x9488)
If you want to use a STM32, I strongly advise that you buy a Nucleo board. They are very cheap. Have an onboard debugger. Have Arduino headers. Are available with several different controllers e.g. 48MHz M0 up to 160MHz M4. You can even buy a Nucleo with the almost-obsolete STM32F103 that is favoured by the elderly stm32uino members.
Following on from rtek1000's comments. Modern STM32 are easier to change GPIO mode. The F103 is very inconvenient.
David.
you want to use a BluePill, wire everything according to the "BluePill Adapter" published on stm32duino Forum.
Do you have a link to the adapter wiring ? I cant find it on the forum
Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
Control pins |RD |WR |RS |CS |RST|
Pin stm32 |PB0|PB6|PB7|PB8|PB9|
Thanks alot, the display (2.4" tft) works but not the touchscreen yet, with the adafruit touchscreen library, the usual mapping for the UNO is as follow: const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341 I tried to reverse engineer it to this for the blue pill (according to the wiring you provided above): const int XP = PA6, XM = PB7, YP = PB6, YM =PA7; //ID=0x9341 But it doesnt work
EDIT: im using the TouchScreen_STM.h library
Hello, I can not access my code now, but I know It needs to be used 2 analog ports, I will soon say the pins I used with another touch
I was able to run the touch of a 3.2 inch display with this setting: (Unfortunately, my 2.4 display was with a damaged touch, I could not make it work)
#include <stdint.h>
#include "TouchScreen_STM.h" // TouchScreen_STM
// These are the pins for the shield!
#if !defined (__STM32F1__)
#define YP A1 // must be an analog pin, use "An" notation! (for Mega)
#define XM A2 // must be an analog pin, use "An" notation! (for Mega)
#define YM 7 // can be a digital pin
#define XP 6 // can be a digital pin
#else
#define YP PB1 // must be an analog pin
#define XM PB0 // must be an analog pin
#define YM PB15 // can be a digital pin
#define XP PB14 // can be a digital pin
#endif
#define MINPRESSURE 10
#define MAXPRESSURE 1000
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
#define Orientation 1
int x_pos, y_pos, z_pos;
#include <Adafruit_GFX.h> // Core graphics library
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include "MCUFRIEND_kbv.h"
MCUFRIEND_kbv tft;
//***********************************************//
// If you use OPEN-SMART TFT breakout board //
// Reconmmend you to add 5V-3.3V level converting circuit.
// Of course you can use OPEN-SMART UNO Black version with 5V/3.3V power switch,
// you just need switch to 3.3V.
// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
//----------------------------------------|
// TFT Breakout -- STM32F103C8 - MEGA shield
// GND -- GND
// 5V -- 5V
// CS -- PB3
// RS/CD (XM) -- PB0
// WR (YP) -- PB1
// RD -- PB4
// RST -- RESET
// LED -- GND
// DB0 -- PB8
// DB1 -- PB9
// DB2 -- PB10
// DB3 -- PB11
// DB4 -- PB12
// DB5 -- PB13
// DB6 (XP) -- PB14
// DB7 (YM) -- PB15
This post can help identify the pins of this shield (need to connect 3.3V and 5V): https://forum.arduino.cc/index.php?topic=516687.msg3521369#msg3521369
@david
Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0| Control pins |RD |WR |RS |CS |RST| Pin stm32 |PB0|PB6|PB7|PB8|PB9|
if WR/RS must be analog , then that mapping wont work for the bluepill right ?
In my case, I was not using touch because the control was done with external buttons
I believe that once the user can understand how to modify the code, there should be no difficulties. But looking at the bluepill pins, it really should not work if you use PB6 and PB7
It may be easier for users, if they can map pins individually, as would be done for 20x2 LCD
LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)
Ref: LiquidCrystal https://www.arduino.cc/en/Tutorial/HelloWorld
@rtek1000 in the mcufriend_shield.h I modified:
#elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8)
#warning Uno Shield on BLUEPILL
#define RD_PORT GPIOB
//#define RD_PIN 5
#define RD_PIN 0 //hardware mod to Adapter. Allows use of PB5 for SD Card
#define WR_PORT GPIOB
#define WR_PIN 6
#define CD_PORT GPIOB
#define CD_PIN 7
#define CS_PORT GPIOB
#define CS_PIN 8
#define RESET_PORT GPIOB
#define RESET_PIN 9
into
#elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8)
#warning Uno Shield on BLUEPILL
#define RD_PORT GPIOB
#define RD_PIN 5 //hardware mod to Adapter. Allows use of PB5 for SD Card
#define WR_PORT GPIOB
#define WR_PIN 1
#define CD_PORT GPIOB
#define CD_PIN 0
#define CS_PORT GPIOB
#define CS_PIN 8
#define RESET_PORT GPIOB
#define RESET_PIN 9
in order to use PB5,PB0,PB1, but the touchscreen didnt work either.
Standard BluePill wiring:
Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
Control pins |RD |WR |RS |CS |RST|
Pin stm32 |PB0|PB6|PB7|PB8|PB9|
The most common Touch wiring on Red shields is:
const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341
However the BluePill is using PB6, PB7 for LCD_WR, LCD_RS which are Digital pins.
So you would use LCD_D7, LCD_D6 for YP, XM because they can be used as Analog pins.
const int XP = PB7, XM = PA6, YP = PA7, YM = PB6; //ID=0x9341
Untested, I strongly advise you to diagnose X, Y pins on a Uno or by using a DMM.
I seldom use a BluePill. Nucleos are much more convenient. And of course they have a sensible pin layout. The "standard" BluePill wiring was chosen purely because a Forum member had made some Adapter pcbs.
David.
If I change XM& YP into analog pins then I have to change the #define WR_PORT #define CD_PORT in the mcufriend_shield.h header too right ?
Hi, my file mcufriend_shield.h looks like this:
//#define USE_SPECIAL //check for custom drivers
#define USE_OPENSMART_SHIELD_PINOUT 1
// ...
#if 0
#elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8)
#warning Uno Shield on BLUEPILL
// configure macros for the data pins
#ifdef USE_OPENSMART_SHIELD_PINOUT
#warning USE OPENSMART SHIELD PINOUT
#define RD_PORT GPIOB
#define RD_PIN 4
#define WR_PORT GPIOB
#define WR_PIN 1
#define CD_PORT GPIOB // RS
#define CD_PIN 0 // RS
#define CS_PORT GPIOB
#define CS_PIN 3
#define RESET_PORT GPIOC
#define RESET_PIN 13
#define setWriteDir() {pinMode(PB4, OUTPUT); \
pinMode(PB5, OUTPUT); \
pinMode(PB1, OUTPUT); \
pinMode(PB0, OUTPUT); \
pinMode(PB15, OUTPUT); \
pinMode(PB14, OUTPUT); \
pinMode(PB13, OUTPUT); \
pinMode(PB12, OUTPUT); \
pinMode(PB11, OUTPUT); \
pinMode(PB10, OUTPUT); \
pinMode(PB9, OUTPUT); \
pinMode(PB8, OUTPUT); \
}
#define setReadDir() { pinMode(PB15, INPUT); \
pinMode(PB14, INPUT); \
pinMode(PB13, INPUT); \
pinMode(PB12, INPUT); \
pinMode(PB11, INPUT); \
pinMode(PB10, INPUT); \
pinMode(PB9, INPUT); \
pinMode(PB8, INPUT); \
}
#define write_8(d) { GPIOB->REGS(BSRR) = 0xFF00 << 16; \
GPIOB->REGS(BSRR) = (d) << 8;}
#define read_8() ((GPIOB->REGS(IDR) >> 8) & 0xFF)
#else
// ...
#endif
#elif IS_NUCLEO64 // Uno Shield on NUCLEO
No. Connect the BluePill with the standard wiring.
When you use the Touchscreen you add the two lines that specify your pins and calibration. The first step is to measure the resistance with a DMM to determine the X, Y pins.
If you use the "Maple" core you will find the calibration will be 12-bit numbers. If you use the ST core Touchscreen.h will use the same 10-bit numbers as a Uno,Mega, ...
David.
No. Connect the BluePill with the standard wiring.
When you use the Touchscreen you add the two lines that specify your pins and calibration. The first step is to measure the resistance with a DMM to determine the X, Y pins.
If you use the "Maple" core you will find the calibration will be 12-bit numbers. If you use the ST core Touchscreen.h will use the same 10-bit numbers as a Uno,Mega, ...
David.
There is something I got radically wrong. 1)XM& YP pins defined in the touch screen setup must be the same as the WR and CD pins right (because in the arduino uno they are the same)? 2)therefore if I change the XM& YP to some analog pin, I must change WR and CD accordingly right ? Or is it that the XM& YP and be programmatically moved around ? The screen works fine on the UNO, and I calibrated it there. I dont think I need to recalibrate it on the bluepill.
Please identify the X and Y with a DMM or Uno. If you don't have a Uno, Megaa, ... say so. If you don't have a DMM, say so. It would take two minutes from your life.
If you simply did as I ask, I would plug a Shield into the BluePill Adapter and try it for myself. I would even try it with both Cores. And with Touchscreen_STM.h and regular Touchscreen.h
Be reasonable. If you are not prepared to spend two minutes, you can't expect others to go down blind alleys on your behalf.
David.
Please identify the X and Y with a DMM or Uno. If you don't have a Uno, Megaa, ... say so. If you don't have a DMM, say so. It would take two minutes from your life.
If you simply did as I ask, I would plug a Shield into the BluePill Adapter and try it for myself. I would even try it with both Cores. And with Touchscreen_STM.h and regular Touchscreen.h
Be reasonable. If you are not prepared to spend two minutes, you can't expect others to go down blind alleys on your behalf.
David.
By X and Y, you mean identify the X and Y pins ? My screen (2.4" TFT uno shield) works fine plugged on an UNO with the settings: const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341 So I guess that identifies the 4 pins enough right? Considering my board has the pinout: http://www.mcufriend.com/2.4_uno/20181120164255.jpg I dont mind using a multimeter but how do I measure in order to find the XY pins ?
That why my earlier message mentionned that it should translate as : const int XP = PA6, XM = PB7, YP = PB6, YM =PA7; //ID=0x9341 on the blue pill. But it doesnt .
Does that answer your question ? I will craft an adapter tomorrow in case the issue is the jumper cables.
Hi, to measure the resistance of X and Y, use the DMM (digital multimeter) on the resistance scale, then try measuring between the pins: LCD_D6 (TOUCH_XP) & LCD_RS (TOUCH_XM). And LCD_D7 (TOUCH_YM) & LCD_WR (TOUCH_YP).
Note: use only DMM + Shield, disconnected from others devices.
#################################################################### Standard BluePill wiring:
Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
Control pins |RD |WR |RS |CS |RST|
Pin stm32 |PB0|PB6|PB7|PB8|PB9|
The most common Touch wiring on Red shields is:
const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341
However the BluePill is using PB6, PB7 for LCD_WR, LCD_RS which are Digital pins.
So you would use LCD_D7, LCD_D6 for YP, XM because they can be used as Analog pins.
#####################################################################
First off. I calibrated this screen with a Uno:
const int XP=6,XM=A2,YP=A1,YM=7; //240x320 ID=0x1602
const int TS_LEFT=92,TS_RT=914,TS_TOP=942,TS_BOT=125;
Then I plugged it into a BluePill Adapter.
Edited the Calibration sketch to match the X, Y pins e.g.
int XP=PB7,XM=PA6,YP=PA7,YM=PB6; //240x320 ID=0x1602
Set the Arduino IDE for the ST Core. Ran the Calibration sketch. And got:
const int TS_LEFT=925,TS_RT=105,TS_TOP=83,TS_BOT=908; //BluePill calibration
Note that the LEFT and RT are swapped. And TOP and BOT are swapped. versus the Uno. This is due to XM, XP are being physically swapped when you use PA6 for XM, PB7 for XP etc.
Also note that the XM, XP, ... report is garbage. It tries to say Arduino pin nomenclature. The BluePill has no official digital numbering. It just uses PA0, PB3, ... style. You have forced XP, XM, etc anyway.
The Calibration sketch works fine on Roger's Maple Core because it uses a native "Touchscreen_kbv" class. (you have to invent some dummy defines for A0, A4, A5)
If you want to use Roger's Core, I suggest that you use my "Touchscreen_kbv" class.
Of course, the ST Core works seamlessly. Oh, you might have to tell Touchscreen.h the type of RwReg e.g.
#if defined(ARDUINO_FEATHER52) || defined(ESP32) || defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__)
typedef volatile uint32_t RwReg;
#endif
############################################################################## To run any Touch example, you just replace the two "const int" lines with your specific calibration. e.g.
const int XP=PB7,XM=PA6,YP=PA7,YM=PB6; //240x320 ID=0x1602
const int TS_LEFT=925,TS_RT=105,TS_TOP=83,TS_BOT=908; //BluePill calibration
############################################################################## David.
Hi Dave, it seems to work, it would help if you could release the blue pill compatible calibration software
I also added the pin mapping to the comments of the shield.h, I suggest you merge my fork.
There is a bug in touchscreen_STM.h, I recommend using touchscreen_kbv.h instead
Hi Dave, it seems to work, it would help if you could release the blue pill compatible calibration software
The regular Touchscreen_Calibration_native sketch from the examples should work as soon as you add the correct XP, XM, YP, YM pins.
Yes I will add the brief Pinout comments for the BluePill to the shield.h file. I don't want to "encourage" BluePill use by making life too easy.
p.s. my name is "David"
Hi David, in TouchScreen_Calibr_native, there is a reference to A0/A4 in diagnose_pins()
Just put in some dummies e.g.
#define A0 0
#define A4 4
#define A5 5
These symbols are only used in the "diagnose pins" which is ignored for ARM.
David.
For David: I followed the work with you and Rtek1000 above. Earlier this month, I have developed a nice LCD data display graphics for our traditional arduino mega based test set product line, using Adafruit Libraries and mcufriend_kbv. I like these libraries because they have so many features.
But... now I have hardware that uses the 16 unused Mega pins to support LCD (and preserves the normal pins for test usages). In order to do this I have made my own pin_arduino.h located in the Program Files (x86) way down in variants\mega directory. Works great when I use the Elegoo Touchscreen libraries. ( I only had to edit pin_magic.h) But certainly I need to change mcufriend_serial.h and mcufriend_special.h to use mcufriend_kbv library. I followed the step where I used my new pins and made a LCD_ID_reading.ino which is verified and produces the exact same registers as traditional Arduino mega. (attached) At one point you said you would make the mcu_friend_serial.h and mcufriend_special.h if the results were verified. I thought I would just follow Rtek1000's posting of the ones you made for him, but the basic files changed a lot since July 20 2018 - mine are dated 5/14/19. If that is too much effort - if you had a more recent example of these two .h files than Rtek1000 - that starts with latest rev of the library, I could probably work through that myself.
Not sure of your role in this, I hope I'm not too presumptive. Please let me know if I am, as I am not on any forums much. Further, what is this BLUEPILL concept I read about (yes I know the Matrix reference).
LCD_ID_readreg_edit_6_25_19.zip
Follow up: Got it working now, so never mind about that above. But, if there is a place I can read about the group that does mcufriend and some of the history, I would appreciate a link or even a short paragraph if there is no link. This library really takes on a lot of different hardware and does some powerful things.
Arduino questions are best asked on Arduino Displays Forum https://forum.arduino.cc Technical issues or Pull Requests are best asked on GitHub
Most people, most of the time use regular shields with regular Arduino boards. Occasionally someone wants to re-route the data bus to PORTA on a Mega2560. Or to use a 16-bit databus on Mega or Due.
These "typical" SPECIALs are already in mcufriend_special.h
The library was intended for shields that plug into Arduino header sockets. Life is easier if you learned about male and female mating in school. Writing a SPECIAL for random pins on the databus is fiddly. I do not intend to make it "friendly".
Yes, there are many changes in the Beta since the last Release. Adding a SPECIAL #elif USE_SOME_CUSTOM_PINOUT block is exactly the same for Beta or Release.
The BLUEPILL is a $2 STM32 board without Arduino headers. The weird STM32 "Roger / Maple" core does not implement Arduino very well. Which means that every punter wants to connect the databus to random pins.
The STM32 Core from STMicroelectronics supports many different STM32 chips and implements Arduino pretty well.
David.
Hello David, I am trying to drive a 3.5" display using BluePill. The display works fine on NUCLEO and UNO. But I can't get it to work on the BluePill. The pins Work fine, i tested individually. The ID of mcufriend LCD is 0x1581. I am using the standard pin configuration:
Standard BluePill wiring:
Port data |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | Pin stm32 |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0|
Control pins |RD |WR |RS |CS |RST| Pin stm32 |PB0|PB6|PB7|PB8|PB9|
But the display is just White. The LCD_ID_readreg output is as follows:
Read Registers on MCUFRIEND UNO shield controllers either read as single 16-bit e.g. the ID is at readReg(0) or as a sequence of 8-bit values in special locations (first is dummy)
reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ... reg(0x0004) 00 00 00 00 Manufacturer ID reg(0x0009) 09 09 09 09 09 Status Register reg(0x000A) 38 08 Get Power Mode reg(0x000C) 08 08 Get Pixel Format reg(0x0061) 01 01 RDID1 HX8347-G reg(0x0062) 00 00 RDID2 HX8347-G reg(0x0063) 01 01 RDID3 HX8347-G reg(0x0064) 00 00 RDID1 HX8347-A reg(0x0065) 01 01 RDID2 HX8347-A reg(0x0066) 00 00 RDID3 HX8347-A reg(0x0067) 01 01 RDID Himax HX8347-A reg(0x0070) 00 00 Panel Himax HX8347-A reg(0x00A1) 01 01 01 01 01 RD_DDB SSD1963 reg(0x00B0) 00 00 RGB Interface Signal Control reg(0x00B4) 00 00 Inversion Control reg(0x00B6) 00 00 00 00 00 Display Control reg(0x00B7) 01 01 Entry Mode Set reg(0x00BF) 09 09 09 09 09 09 ILI9481, HX8357-B reg(0x00C0) 00 00 32 00 00 00 02 00 42 Panel Control reg(0x00C8) 08 08 08 08 08 08 08 08 08 08 08 08 08 GAMMA reg(0x00CC) 08 08 Panel Control reg(0x00D0) 00 00 00 Power Control reg(0x00D2) 00 00 00 00 00 NVM Read reg(0x00D3) 01 01 01 01 ILI9341, ILI9488 reg(0x00D4) 00 00 00 00 Novatek ID reg(0x00DA) 08 08 RDID1 reg(0x00DB) 09 09 RDID2 reg(0x00DC) 08 08 RDID3 reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P reg(0x00E1) 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 GAMMA-N reg(0x00EF) 09 09 09 09 09 09 ILI9327 reg(0x00F2) 00 00 00 A0 A0 00 00 00 00 00 00 00 Adjust Control 2 reg(0x00F6) 00 00 00 00 Interface Control
My IDE version is 1.8.8, i am using stm32duino core and i reinstalled the IDE + Libraries.
I need to submit this as a project in University, any help is appreciated.
And keep up the good work !
Mateen
I suggest that you check your BluePill wiring. Did you edit the defines in LCD_ID_readreg to match your wiring?
Is there any reason for not using a Nucleo board? Shields plug straight in. You never worry about "wiring" correctly.
Which Nucleo? I suggest that you use the STM32 Core from STMicroelectronics.
David.
I used NUCLEO F-103RB but thanks for the help, one of the wire was not properly connected.
Now i need help to get the SD card working. Wiring seems to be okay. I am connecting as follows:
SD_SS PA15 SD_DI PB5 SD_DO PB4 SD_SCK PB3
I have also swapped the DI and DO lines to see if it works. I have also changed the SD_CS pin to PA15. In the serial it says "cannot start SD"
#define SD_CS PA15
I have double checked the wiring and the SD_card works too. I am using the show_BMP example. Using UNO and NUCLEO it does show the BMP images but not in the case of BluePill
Thanks for your Help.
I used NUCLEO F-103RB but thanks for the help, one of the wire was not properly connected.
Now i need help to get the SD card working. Wiring seems to be okay. I am connecting as follows:
SD_SS PA15 SD_DI PB5 SD_DO PB4 SD_SCK PB3
I have also swapped the DI and DO lines to see if it works. I have also changed the SD_CS pin to PA15. In the serial it says "cannot start SD". Double checked the wiring and the SD_card works too. I am using the show_BMP example. Using UNO and NUCLEO it does show the BMP images but not in the case of BluePill.
#define SD_CS PA15
Thanks for your Help.
I do not understand how you can I used NUCLEO F-103RB but thanks for the help, one of the wire was not properly connected. The Shield plugs straight into the Nucleo headers. Nucleos come with headers already mounted.
All Graphics, Touch, SD, I2C, ... should work perfectly with the STM Core on any Nucleo. e.g. showBMP_kbv_Uno
If you want to use Roger's weird Maple Core you will have to make allowances for his disdain for Nucleo. Yes, I know how to adapt for Roger's Core. I do it for the TFT. I am not prepared to do it for every other inconvenience.
Why do you want to use a BluePill?
David.
I used a NUCLEO earlier. But NUCLEO is not allowed on the project, on the other hand BluePill can be used. Allowed by supervisor. All of the other things (RTC, OneWire) i have got working with the BluePill. But sadly SD card is getting tougher. Has anyone every successfully run showBMP_kbv_Uno on bluepill? I just need the SD card for showing some pics and logos. My apologies, i confused you that i was using NUCLEO but i am only using it for checking if the shield works or not. My project uses the BluePill.
Please help regarding the SD card. I cannot use the ST core because the RTC and OneWire library are not supported by that. I have also installed the ST core but SD card doesn't even work on that.
I strongly recommend that you use the STM Core. There is no reason for OneWire or RTC to be different on the STM Core.
Yes, I have used SD Card on a BluePill with both Roger's Core and the proper STM Core.
It seems a good strategy to develop on the Nucleo. Built-in ST-Link. Built-in Serial. Built-in headers. Re-compile with BluePill as target after the develop, debug, test is complete.
David.
The attached zip contains an excel sheet with which, setting the wanted pins, you can generate automatically the code to insert in mcufriend_special.h
I hope it will be useful.
I don't have ExCel. I tried to run it in OpenOffice but it failed.
What does the output look like?
I have often wondered about making the macros easier. But concluded that I would just get constant grief from BluePill owners.
Of course their are many other targets in the world e.g. Xmega, LGT8F, Teensy, ESP32, ...
At least ST Nucleo boards have the same pinout (unlike NXP)
David.
I realized the generation of macros in excel because using Visual Basic for Application was the fastest way.
I attached the image of input, the output is the code to paste in mcufriend_special.h with the right macros calculated using the input.
Regards
GPA
I can see the input screen. i.e. just like in your message.
I would like to see the output. i.e. what a punter would paste into mcufriend_special.h
David.
This is the output for the shown configuration:
#if defined(ARDUINO_BLUEPILL_F103C8) //regular CMSIS libraries
#define REGS(x) x
#define GPIO_INIT() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#else //weird Maple libraries
#define REGS(x) regs->x
#endif
#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444)
#define PIN_OUTPUT(port, pin) {
if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));}
else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));}
}
#define PIN_INPUT(port, pin) {
if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); }
else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); }
}
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))
#define RD_PORT GPIOA #define RD_PIN 0 #define WR_PORT GPIOA #define WR_PIN 1 #define CD_PORT GPIOA #define CD_PIN 2 #define CS_PORT GPIOA #define CS_PIN 3 #define RESET_PORT GPIOA #define RESET_PIN 4
// configure macros for the data pins
#define AMASK 0x0000
#define BMASK 0x0FF0
#define write_8(d) { GPIOA->REGS(BSRR) = AMASK << 16; GPIOB->REGS(BSRR) = BMASK << 16;
GPIOB->REGS(BSRR) = (((d) & 0xFF)<< 4);
}
#define read_8() (((GPIOB->REGS(IDR) & 0xFF0)>> 4))
//
#define setWriteDir() {GP_OUT(GPIOB, CRH, 0x0000FFFF); GP_OUT(GPIOB, CRL, 0xFFFF0000); }
#define setReadDir() {GP_INP(GPIOB, CRH, 0x0000FFFF); GP_INP(GPIOB, CRL, 0xFFFF0000); }
#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
You have pasted an "easy" case. It looks fine.
Please can you post a "random" case e.g. data bus with different port pins in random order. And control pins on random pins
That would be a real test. Certainly make my life easier. And any machine generated SPECIALs will be without typos !!
David.
I attached the OpenOffice version.
Please let me know if it works also for "random" case. Thanks
GPA
I downloaded the OpenOffice version. And enabled Macros.
Then added a line with the Nucleo-64 pinout
Nucleo64 | PA8 | PB10 | PB4 | PB5 | PB3 | PA10 | PC7 | PA9 | | PA0 | PA1 | PA2 | PA3 | PB0
And copy-pasted this line to Row#2. This generated correct code for the control pins. But did not generate code for LCD_D1 i.e. PC7 And incorrect comment for the setWriteDir() lines
I am impressed. It seems to generate code for the obsolete STM32F103 Most current STM32 use MODER register.
David.
Hello,
@prenticedavid Interesting, where can I find the information that this STM32F103 is obsolete? https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html
@giaava Thanks for helping!
The VBA code, actually, works only with PORTA and PORTB but can easly modified to support PORTC
The generated code is almost the same (except macro) of the original mcufriend_special.h in which is present the code for STM32F103
GPA
It is not obsolete. But I certainly would never choose it for a new design.
ST have a good range of modern STM32 Nucleo and Discovery boards.
Punters like the BluePill because it is so cheap. It would seem wiser for these to be replaced by M4 devices.
It is an excellent idea to automate the SPECIAL for common STM32 devices. Even better if it can be adapted for NXP, Atmel, TI, etc.
Nucleo-64 is spread over three Ports. Nucleo-144 is spread over 3 Ports. (EDIT corrected from 4 to 3) So it would be useful to have a spreadsheet that can handle 3 Ports.
David.
@giaava Thank you very much for creating the spreadsheet. I ran into an issue with another library that only worked on spi1 on PA4-PA7. This allowed me to move things around and get everything working.
The spreadsheet is impressive. I have always done the write_8(), read_8(), setWriteDir(), ... by hand. They do not always work first time.
It would be nice if giaava extended the spreadsheet to cope with GPIOC and GPIOD.
David.