Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 08:40 26 Jun 2022 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Adding a chip with a different number of pins to a MMBasic port

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6225
Posted: 09:49am 30 Nov 2021
Copy link to clipboard 
Print this post

This post is by way of a tutorial as to how to add a chip with a different number of pins to a MMbasic port. This is in response to a suggestion to support a 100-pin STM32H743 based PCB with the ArmmiteH7 code but applies to any of my ports (and in fact to the MM2/MM+ as like most things the concept was created by Geoff). I'm very happy for anyone to take any of my code sets and enhance them to support different chip variants which I can then integrate if they follow the approach I'm documenting here.

The first step is for the firmware to know how many pins there are on the chip running the firmware

In the STM32 this is found by reading a special location in the chips's I/O space. I'll use an example from the ArmmiteL4 code

#define package (*(volatile unsigned int *)(PACKAGE_BASE) & 0b11111)


PACKAGE_BASE is defined in the chips hardware abstraction layer in the files used by STM32CubeIDE

This returns a coded value which can identify the number of pins

#define HAS_64PINS          (package==0)
#define HAS_32PINS          (package==0x8)
#define HAS_48PINS          (package==0xB)
#define NBR_PINS_32CHIP    32    // number of pins for external i/o on a 32 pin chip
#define NBR_PINS_48CHIP    48    // number of pins for external i/o on a 48 pin chip
#define NBR_PINS_64CHIP    64    // number of pins for external i/o on a 64 pin chip
#define NBRPINS                ({int j=32; if(HAS_32PINS)j=NBR_PINS_32CHIP; if(HAS_48PINS)j=NBR_PINS_48CHIP;if(HAS_64PINS)j=NBR_PINS_64CHIP; j ;})


These definitions are then used throughout the code but the most important use is in selecting the pin map for the chip - everything internal to MMBasic works on physical pin numbers. This is found in the file ioports.h

struct s_PinDef *PinDef;
const struct s_PinDef PinDef32[NBR_PINS_32CHIP + 1]={
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 0
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 1 VDD
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 2 OSC32_IN
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 3 OSC32_OUT
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 4 NRST
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 5 VDD
{ GPIOA,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_5},     // pin 6 COUNT/WAKEUP/IR
   { GPIOA,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_6},     // pin 7 SPI-CLK
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 8 Console-TX

{ GPIOA,  GPIO_PIN_3,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_8},     // pin 9 PWM2A
{ GPIOA,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_9},     // pin 10 DAC1
   { GPIOA,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_10},    // pin 11 DAC2
   { GPIOA,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_11},    // pin 12 SPI-IN
   { GPIOA,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_12},    // pin 13 SPI-OUT
   { GPIOB,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_15},    // pin 14
   { GPIOB,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_16},    // pin 15 COUNT
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 16 VSS

   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 17 VDD
{ GPIOA,  GPIO_PIN_8,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 18 PWM1A
{ GPIOA,  GPIO_PIN_9,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 19 COM1-TX/ PWM1C
{ GPIOA,  GPIO_PIN_10, DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 20 COM1-RX/ PWM1D
{ GPIOA,  GPIO_PIN_11, DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 21 PWM1B
   { GPIOA,  GPIO_PIN_12,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 22 USART1-DE/COUNT
{ GPIOA,  GPIO_PIN_13,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 23 SWDIO - not broken out on Nucleo
{ GPIOA,  GPIO_PIN_14,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 24 SWCLK - not broken out on Nucleo

{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 25 Console-RX
   { GPIOB,  GPIO_PIN_3,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 26 Green-LED/SPI2-CLK
   { GPIOB,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 27 SPI2-IN
   { GPIOB,  GPIO_PIN_5, DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 28 SPI2-OUT
   { GPIOB,  GPIO_PIN_6, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 29 I2C-SCL
{ GPIOB,  GPIO_PIN_7, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 30 I2C-SDA
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 31 BOOT0
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 32 VSS
};
const struct s_PinDef PinDef48[NBR_PINS_48CHIP + 1]={
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 0
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 1 VBAT
{ GPIOC,  GPIO_PIN_13,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 2
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 3 OSC32_IN
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 4 OSC32_OUT
   { GPIOH,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 5
   { GPIOH,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 6
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 7 NRST
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 8 VSSA
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 9 VDDA
{ GPIOA,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_5},     // pin 10 COUNT/WAKEUP/IR
   { GPIOA,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_6},     // pin 11 SPI-CLK
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 12 CONSOLE-TX

{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 13 CONSOLE-RX
   { GPIOA,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_9},     // pin 14 DAC-1
   { GPIOA,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_10},    // pin 15 DAC-2
   { GPIOA,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_11},    // pin 16 SPI-IN
   { GPIOA,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_12},    // pin 17 SPI-OUT
   { GPIOB,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_15},    // pin 18
   { GPIOB,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_16},    // pin 19 COUNT
   { GPIOB,  GPIO_PIN_2,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 20
   { GPIOB,  GPIO_PIN_10,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 21 COM2-TX
   { GPIOB,  GPIO_PIN_11,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 22 COM2-RX
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 23 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 24 VDD

   { GPIOB,  GPIO_PIN_12,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 25
   { GPIOB,  GPIO_PIN_13,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 26 SPI3-CLK
   { GPIOB,  GPIO_PIN_14,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 27 SPI3-IN
   { GPIOB,  GPIO_PIN_15,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 28 SPI3-OUT
   { GPIOA,  GPIO_PIN_8, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 29 PWM1A
   { GPIOA,  GPIO_PIN_9, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 30 COM1-TX / PWM1C
   { GPIOA,  GPIO_PIN_10, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 31 COM1-RX / PWM1D
   { GPIOA,  GPIO_PIN_11, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 32 PWM1B
   { GPIOA,  GPIO_PIN_12, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 33 COM1-DE /COUNT
   { GPIOA,  GPIO_PIN_13, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 34 SWDIO
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 35 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 36 VDD
//
   { GPIOA,  GPIO_PIN_14, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 37 SWCLK
   { GPIOA,  GPIO_PIN_15,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 38
   { GPIOB,  GPIO_PIN_3,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 39 SPI2-CLK
   { GPIOB,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 40 SPI2-IN
   { GPIOB,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 41 SPI2-OUT
   { GPIOB,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 42 I2C-SCL
   { GPIOB,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 43 I2C-SDA
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 44 BOOT0
{ GPIOB,  GPIO_PIN_8, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 45 PWM2A
{ GPIOB,  GPIO_PIN_9, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 46
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 47 VSS
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 48 VDD
};
const struct s_PinDef PinDef64[NBR_PINS_64CHIP + 1]={
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 0
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 1 VBAT
{ GPIOC,  GPIO_PIN_13,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 2
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 3 OSC32_IN
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 4 OSC32_OUT
   { GPIOH,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 5
   { GPIOH,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 6
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 7 NRST
{ GPIOC,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_1},     // pin 8 -A5
{ GPIOC,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_2},     // pin 9 -A4
{ GPIOC,  GPIO_PIN_2,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_3},     // pin 10
{ GPIOC,  GPIO_PIN_3,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_4},     // pin 11
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 12 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 13 VDD
{ GPIOA,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_5},     // pin 14 COUNT/WAKEUP/IR -A0
   { GPIOA,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_6},     // pin 15 SPI-CLK -A1
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 16 CONSOLE-TX -D1
//
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 17 CONSOLE-RX -D0
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 18 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 19 VDD
   { GPIOA,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_9},     // pin 20 DAC-1 -A2
   { GPIOA,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_10},    // pin 21 DAC-2 -D13
   { GPIOA,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_11},    // pin 22 SPI-IN -D12
   { GPIOA,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_12},    // pin 23 SPI-OUT -D11
{ GPIOC,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN ,  ADC1, ADC_CHANNEL_13},   // pin 24
{ GPIOC,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN ,  ADC1, ADC_CHANNEL_14},   // pin 25
   { GPIOB,  GPIO_PIN_0,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_15},    // pin 26 -A3
   { GPIOB,  GPIO_PIN_1,  DIGITAL_IN | DIGITAL_OUT | ANALOG_IN , ADC1, ADC_CHANNEL_16},    // pin 27 COUNT
{ GPIOB,  GPIO_PIN_2,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},        // pin 28
   { GPIOB,  GPIO_PIN_10,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 29 COM2-TX -D6
   { GPIOB,  GPIO_PIN_11,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 30 COM2-RX
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 31 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 32 VDD
//
   { GPIOB,  GPIO_PIN_12,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 33
   { GPIOB,  GPIO_PIN_13,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 34 SPI3-CLK
   { GPIOB,  GPIO_PIN_14,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 35 SPI3-IN
   { GPIOB,  GPIO_PIN_15,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 36 SPI3-OUT
{ GPIOC,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 37
{ GPIOC,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 38 -D9
{ GPIOC,  GPIO_PIN_8,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 39
{ GPIOC,  GPIO_PIN_9,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 40
   { GPIOA,  GPIO_PIN_8, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 41 PWM1A -D7
   { GPIOA,  GPIO_PIN_9, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 42 COM1-TX / PWM1C -D8
   { GPIOA,  GPIO_PIN_10, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 43 COM1-RX / PWM1D -D2
   { GPIOA,  GPIO_PIN_11, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 44 PWM1B
   { GPIOA,  GPIO_PIN_12, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 45 COM1-DE /COUNT
{ GPIOA,  GPIO_PIN_13, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 46 SWDIO
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 47 VSS
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 48 VDD
//
   { GPIOA,  GPIO_PIN_14, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 49 SWCLK
   { GPIOA,  GPIO_PIN_15,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 50
{ GPIOC,  GPIO_PIN_10,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 51
{ GPIOC,  GPIO_PIN_11,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 52
{ GPIOC,  GPIO_PIN_12,  DIGITAL_IN | DIGITAL_OUT,  NULL, 0},     // pin 53
   { GPIOD,  GPIO_PIN_2,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 54
   { GPIOB,  GPIO_PIN_3,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 55 SPI2-CLK -D3
   { GPIOB,  GPIO_PIN_4,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 56 SPI2-IN -D5
   { GPIOB,  GPIO_PIN_5,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 57 SPI2-OUT -D4
   { GPIOB,  GPIO_PIN_6,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 58 I2C-SCL -D10
   { GPIOB,  GPIO_PIN_7,  DIGITAL_IN | DIGITAL_OUT , NULL, 0},     // pin 59 I2C-SDA
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 60 BOOT0
{ GPIOB,  GPIO_PIN_8, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 61 PWM2A -D15
{ GPIOB,  GPIO_PIN_9, DIGITAL_IN | DIGITAL_OUT , NULL, 0},       // pin 62 -D14
{ NULL,  0, PUNUSED , NULL, 0},                                                       // pin 63 VSS
   { NULL,  0, PUNUSED , NULL, 0},                                                       // pin 64 VDD
};


As part of the initialisation of MMBasic the main program assigns one of these tables to the PinDef definition to be used

if(HAS_32PINS)PinDef=(struct s_PinDef *)PinDef32;
if(HAS_48PINS)PinDef=(struct s_PinDef *)PinDef48;
if(HAS_64PINS)PinDef=(struct s_PinDef *)PinDef64;


So the firmware now knows how many pins there are (NBRPINS) and which pin on which I/O port is assigned to each physical pin.

There is one more step that needs establishing - which pins are used for the various special functions (I2C, UARTs, SPI, PWM etc.). This is done with another set of definitions

// INT1PIN refers to the PIC32 external interrupt #1, an so on for the others
#define INT1PIN              (HAS_32PINS ? 6  : (HAS_48PINS ? 10 : 14))  //PA0
#define INT2PIN              (HAS_32PINS ? 22 : (HAS_48PINS ? 33 : 45))  //PA12
#define INT3PIN              (HAS_32PINS ? 15 : (HAS_48PINS ? 19 : 27))  //PB1
#define IRPIN                (HAS_32PINS ? 6  : (HAS_48PINS ? 10 : 14))  //PA0
//#define COUNT5 (HAS_32PINS ? 11 : 15)  //PA5
// I2C pin numbers
#define P_I2C_SCL            (HAS_32PINS ? 29 : (HAS_48PINS ? 42 : 58))  //PB6
#define P_I2C_SDA            (HAS_32PINS ? 30 : (HAS_48PINS ? 43 : 59))  //PB7

   // Console pin numbers
#define CONSOLE_RX_PIN (HAS_32PINS ? 25 : (HAS_48PINS ? 13 : 17))  //PA15/PA3/PA3 USART2
#define CONSOLE_TX_PIN (HAS_32PINS ? 8  : (HAS_48PINS ? 12 : 16))  //PA2
// COMx: port pin numbers
#define COM1_TX_PIN          (HAS_32PINS ? 19 : (HAS_48PINS ? 30 : 42))  //PA9 USART1
#define COM1_RX_PIN          (HAS_32PINS ? 20 : (HAS_48PINS ? 31 : 43))  //PA10
#define COM1_EN_PIN (HAS_32PINS ? 22 : (HAS_48PINS ? 33 : 45))  //PA12

#define COM2_TX_PIN          (HAS_32PINS ? 0  : (HAS_48PINS ? 21 : 29))  //PB10 USART3
#define COM2_RX_PIN          (HAS_32PINS ? 0  : (HAS_48PINS ? 22 : 30))  //PB11

// SPI pin numbers
#define SPI_CLK_PIN          (HAS_32PINS ? 7  : (HAS_48PINS ? 11 : 15))  //PA1
#define SPI_INP_PIN          (HAS_32PINS ? 12 : (HAS_48PINS ? 16 : 22))  //PA6
#define SPI_OUT_PIN          (HAS_32PINS ? 13 : (HAS_48PINS ? 17 : 23))  //PA7

#define SPI2_CLK_PIN         (HAS_32PINS ? 26 : (HAS_48PINS ? 39 : 55))  //PB3
#define SPI2_INP_PIN         (HAS_32PINS ? 27 : (HAS_48PINS ? 40 : 56))  //PB4
#define SPI2_OUT_PIN         (HAS_32PINS ? 28 : (HAS_48PINS ? 41 : 57))  //PB5

#define SPI3_CLK_PIN         (HAS_32PINS ? 0  : (HAS_48PINS ? 26 : 34))  //PB13
#define SPI3_INP_PIN         (HAS_32PINS ? 0  : (HAS_48PINS ? 27 : 35))  //PB14
#define SPI3_OUT_PIN         (HAS_32PINS ? 0  : (HAS_48PINS ? 28 : 36))  //PB15

// DAC pin numbers
#define DAC_1_PIN            (HAS_32PINS ? 10 : (HAS_48PINS ? 14 : 20))  //PA4
#define DAC_2_PIN            (HAS_32PINS ? 11 : (HAS_48PINS ? 15 : 21))  //PA5
//
// PWM pin numbers
#define PWM_CH1_PIN          (HAS_32PINS ? 18 : (HAS_48PINS ? 29 : 41))  //PA8   - PWM1A
#define PWM_CH2_PIN          (HAS_32PINS ? 21 : (HAS_48PINS ? 32 : 44))  //PA11  - PWM1B
#define PWM_CH3_PIN          (HAS_32PINS ? 19 : (HAS_48PINS ? 30 : 42))  //PA9   - PWM1C
#define PWM_CH4_PIN          (HAS_32PINS ? 20 : (HAS_48PINS ? 31 : 43))  //PA10  - PWM1D
#define PWM_CH5_PIN          (HAS_32PINS ? 9  : (HAS_48PINS ? 45 : 61))  //PA3/PB8/PB8   - PWM2A


We try and keep the same pin/port combination in place for each special function. e.g. SPI2_OUT_PIN is always on PB5 but this may not always be possible (e.g. CONSOLE_RX_PIN). In the later case the initialisation of the console is going to need some special case code to deal with the fact a different pin is used

 if(!HAS_32PINS)goto skipit;
   /* Peripheral clock enable */
   __HAL_RCC_USART2_CLK_ENABLE();
 
   /**USART2 GPIO Configuration    
   PA2     ------> USART2_TX
   PA15 (JTDI)     ------> USART2_RX
   */
   GPIO_InitStruct.Pin = GPIO_PIN_2;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

   GPIO_InitStruct.Pin = GPIO_PIN_15;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF3_USART2;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

   /* USART2 interrupt Init */
   HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(USART2_IRQn);
   return;
   skipit:;
   __HAL_RCC_USART2_CLK_ENABLE();
   GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_PULLUP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(USART2_IRQn);


We try and minimise this requirement to use special case code by the careful allocation of pins to functions. Note also in the allocations SPI3 pins are set to 0 if the chip only has 32 pins as SPI3 isn't supported on this chip - this will also require special case code that blocks SPI3 commands and functions if the chip only has 32 pins.

Next we come to the issue of supporting external devices where the pin usage is defined by the layout of the target board. For example a specific PCB may have the SDcard slot hardwired or a flash memory chip on a specific SPI port. In this case to properly support the board we may need more special cases. The worst case is where a SDcard has been wired to SDIO pins but we need to drive it using SPI. In this case we will need to bitbang the SPI rather than using H/W SPI (not an issue, this is what the CMM2 does by default).

Finally in the case of larger chips which support 16-bit parallel LCD displays we may want to use different ports on different chips to avoid overlapping other special functions.

The example here is from the PIC32MZ port

// the SSD1963 data pins
#define SSD1963_DAT1        (HAS_100PINS ? 25 : 114)  //B0,J0
#define SSD1963_DAT2        (HAS_100PINS ? 24 : 115)  //B1,J1
#define SSD1963_DAT3        (HAS_100PINS ? 23 : 116)  //B2,J2
#define SSD1963_DAT4        (HAS_100PINS ? 22 : 117)  //B3,J3
#define SSD1963_DAT5        (HAS_100PINS ? 21 : 131)  //B4,J4
#define SSD1963_DAT6        (HAS_100PINS ? 20 : 132)  //B5,J5
#define SSD1963_DAT7        (HAS_100PINS ? 26 : 133)  //B6,J6
#define SSD1963_DAT8        (HAS_100PINS ? 27 : 134)  //B7,J7
#define SSD1963_DAT9        (HAS_100PINS ? 32 :   7)  //B8,J8
#define SSD1963_DAT10       (HAS_100PINS ? 33 :   8)  //B9,J9
#define SSD1963_DAT11       (HAS_100PINS ? 34 :  10)  //B10,J10
#define SSD1963_DAT12       (HAS_100PINS ? 35 :  27)  //B11,J11
#define SSD1963_DAT13       (HAS_100PINS ? 41 :   9)  //B12,J12
#define SSD1963_DAT14       (HAS_100PINS ? 42 :  28)  //B13,J13
#define SSD1963_DAT15       (HAS_100PINS ? 43 :  29)  //B14,J14
#define SSD1963_DAT16       (HAS_100PINS ? 44 :  30)  //B15,J15

// the SSD1963 write pin
#define SSD1963_WR_PIN      (HAS_100PINS ? 97 : 141) //G13
#define SSD1963_WR_TOGGLE_PIN   {LATGINV = 1 << 13 ;asm("NOP");}

// the SSD1963 data/command pin.  On the LCD it is labeled RS.
#define SSD1963_DC_PIN      (HAS_100PINS ? 96 : 140) //G12

// the SSD1963 reset pin
#define SSD1963_RESET_PIN   (HAS_100PINS ? 95 : 139) //G14


Here the 100 pin chip uses port B for the 16 bit bus whereas the 144-pin chip can use port J which doesn't exist on the smaller chip

Overall, the process of adapting a MMbasic port to a different size chip from the same family with or without a particular board layout is easy but it is a lot of slog work first to define the main pin setup and then deal with the inevitable special cases. This is why I can't respond to every request but am happy for anyone to take on the work where there is a useful requirement like supporting a cheap and readily available new development board.
Edited 2021-11-30 20:11 by matherp
 
chuckallisonusa
Newbie

Joined: 04/12/2021
Location: United States
Posts: 2
Posted: 02:41am 04 Dec 2021
Copy link to clipboard 
Print this post

All,  
 I am new to the game here and new to stm32 mcu programming. I am looking to port the l series to the G series. The nucleo boards for the g0 and G4 series seem quite capable and have decent flash space. I would like to discuss with someone about how close in abilities the G series and L series are.  

Thanks for your consideration,

Chuck Allison
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2022