Hi,
To understand the register mappings on different PDK CPU types better I created a list (based on include files from original IDE).
https://github.com/free-pdk/fppa-pdk-documentation/blob/master/PDK_register_mapping_scroll_right.csv
Attached is a colorful version as PNG from it.
Based on this info (most registers jump around for different types and only a few number remains static) I think the best idea would be to create one include file per supported processor like:
pdk/pmc150c.h
pdk/pfs154.h
pdk/pfs173.h
...
I fully agree with this approach. I wonder, has anybody already been looking into this? Right now, I am cleaning up some of my old examples. So far I have defined everything in line.
I'm working on it. Right now I work on a PMS150C based project and created a full include file for it. Right now I wait for PCB delivery. As soon as it's done I will put the project online.
Fixing the PDK13 bit SDCC compiler was one of the time consuming tasks, but now it seems to be very stable (same as for PDK14/PDK15).
JS
work in progress:
pms150c.h
#ifndef __PMS150C_H__
#define __PMS150C_H__
#include "pdkcommon.h"
//set calibration macros
#define EASY_PDK_CALIBRATE_IHRC EASY_PDK_CALIBRATE_IHRC_H8
#define EASY_PDK_CALIBRATE_ILRC EASY_PDK_CALIBRATE_IHRC_L8
//IO register definitions
//__sfr __at(0x00) _flag;
//0x01
//__sfr __at(0x02) _sp;
__sfr __at(0x03) _clkmd;
__sfr __at(0x04) _inten;
__sfr __at(0x05) _intrq;
__sfr __at(0x06) _t16m;
//0x07
//0x08
__sfr __at(0x09) _tm2b;
__sfr __at(0x0a) _eoscr;
__sfr __at(0x0b) _ihrcr;
__sfr __at(0x0c) _integs;
__sfr __at(0x0d) _padier;
//0x0e
//0x0f
__sfr __at(0x10) _pa;
__sfr __at(0x11) _pac;
__sfr __at(0x12) _paph;
//0x13
//0x14
//0x15
//0x16
__sfr __at(0x17) _tm2s;
//0x18
__sfr __at(0x19) _bgtr;
__sfr __at(0x1a) _gpcc;
__sfr __at(0x1b) _misc;
__sfr __at(0x1c) _tm2c;
__sfr __at(0x1d) _tm2ct;
__sfr __at(0x1e) _gpcs;
__sfr __at(0x1f) _ilrcr;
//T16C register
__sfr16 _t16c;
//clkmd definitions
#define CLKMD_ENABLE_PA5RST 0x01
#define CLKMD_ENABLE_WATCHDOG 0x02
#define CLKMD_ENABLE_ILRC 0x04
#define CLKMD_ENABLE_IHRC 0x10
#define CLKMD_IHRC_DIV2 0x20
#define CLKMD_IHRC_DIV4 0x00
#define CLKMD_IHRC_DIV8 0x28
#define CLKMD_IHRC_DIV16 0x08
#define CLKMD_IHRC_DIV32 0x68
#define CLKMD_IHRC_DIV64 0x88
#define CLKMD_ILRC 0xe0
#define CLKMD_ILRC_DIV4 0xc0
//interrupt enable definitions
#define INTEN_PA0 0x01
#define INTEN_T16 0x04
#define INTEN_COMP 0x10
#define INTEN_TM2 0x40
//interrupt request definitions
#define INTRQ_PA0 0x01
#define INTRQ_T16 0x04
#define INTRQ_COMP 0x10
#define INTRQ_TM2 0x40
//tm16 definitions
#define T16_INTSRC_8BIT 0x00
#define T16_INTSRC_9BIT 0x01
#define T16_INTSRC_10BIT 0x02
#define T16_INTSRC_11BIT 0x03
#define T16_INTSRC_12BIT 0x04
#define T16_INTSRC_13BIT 0x05
#define T16_INTSRC_14BIT 0x06
#define T16_INTSRC_15BIT 0x07
#define T16_CLK_DIV1 0x00
#define T16_CLK_DIV4 0x08
#define T16_CLK_DIV16 0x10
#define T16_CLK_DIV64 0x18
#define T16_CLK_DISABLE 0x00
#define T16_CLK_SYSCLK 0x20
#define T16_CLK_PA4_FALL 0x60
#define T16_CLK_IHRC 0x80
#define T16_CLK_ILRC 0xC0
#define T16_CLK_PA0_FALL 0xE0
//eosc definitions
#define EOSC_LVD_BANDGAP_SHUTDOWN 0x01
//integs definitions
#define INTEGS_PA0_BOTH 0x00
#define INTEGS_PA0_RISING 0x01
#define INTEGS_PA0_FALLING 0x02
#define INTEGS_T16_RISING 0x00
#define INTEGS_T16_FALLING 0x04
#define INTEGS_COMP_BOTH 0x00
#define INTEGS_COMP_RISING 0x40
#define INTEGS_COMP_FALLING 0x80
//padie definitions
#define PADIE_PA0_WAKEUP_ENABLE 0x01
#define PADIE_PA3_WAKEUP_ENABLE 0x08
#define PADIE_PA4_WAKEUP_ENABLE 0x10
#define PADIE_PA5_WAKEUP_ENABLE 0x20
#define PADIE_PA6_WAKEUP_ENABLE 0x40
#define PADIE_PA7_WAKEUP_ENABLE 0x80
//misc definitions
#define MISC_WATCHDOG_8K_ILRC 0x00
#define MISC_WATCHDOG_16K_ILRC 0x01
#define MISC_WATCHDOG_64K_ILRC 0x02
#define MISC_WATCHDOG_256K_ILRC 0x03
#define MISC_LVR_DISABLE 0x04
#define MISC_FAST_WAKEUP_ENABLE 0x20
//tm2c definitions
#define TM2C_CLK_DISABLE 0x00
#define TM2C_CLK_SYSCLK 0x10
#define TM2C_CLK_IHRC 0x20
#define TM2C_CLK_EOSC 0x30
#define TM2C_CLK_ILRC 0x40
#define TM2C_CLK_COMPOUT 0x50
#define TM2C_CLK_PA0_RISE 0x80
#define TM2C_CLK_PA0_FALL 0x90
#define TM2C_CLK_PB0_RISE 0xA0
#define TM2C_CLK_PB0_FALL 0xB0
#define TM2C_CLK_PA4_RISE 0xC0
#define TM2C_CLK_PA4_FALL 0xD0
#define TM2C_OUT_DISABLE 0x00
#define TM2C_OUT_PB2 0x04
#define TM2C_OUT_PA3 0x08
#define TM2C_OUT_PB4 0x0C
#define TM2C_MODE_PERIOD 0x00
#define TM2C_MODE_PWM 0x02
#define TM2C_INVERT_OUT 0x01
//tm2s definitions
#define TM2S_PWM_RES_8BIT 0x00
#define TM2S_PWM_RES_6BIT 0x80
#define TM2S_PRESCALE_NONE 0x00
#define TM2S_PRESCALE_DIV4 0x20
#define TM2S_PRESCALE_DIV16 0x40
#define TM2S_PRESCALE_DIV64 0x60
//gpcc definitions
#define GPCC_COMP_PLUS_VINT 0x00
#define GPCC_COMP_PLUS_PA4 0x01
#define GPCC_COMP_MINUS_PA3 0x00
#define GPCC_COMP_MINUS_PA4 0x02
#define GPCC_COMP_MINUS_BANDGAP_1V2 0x04
#define GPCC_COMP_MINUS_VINT_R 0x06
#define GPCC_COMP_MINUS_PA6 0x08
#define GPCC_COMP_MINUS_PA7 0x0A
//gpcs definitions
#define GPCS_COMP_CASE1 0x00
#define GPCS_COMP_CASE2 0x10
#define GPCS_COMP_CASE3 0x20
#define GPCS_COMP_CASE4 0x30
#define GPCS_COMP_WAKEUP_ENABLE 0x40
#define GPCS_COMP_OUTPUT_PA0 0x80
//__PMS150C_H__
pdkcommon.h
#ifndef __PDKCOMMON_H__
#define __PDKCOMMON_H__
//macros so we can use defines in assembler strings
#define _STRINGIFY(x)
#define _ASMV(x) "_"_STRINGIFY(x)
#define _ASMD(x) _STRINGIFY(x)
//definitions for built in opcodess
#define __engint() __asm__("engint\n")
#define __disgint() __asm__("disgint\n")
#define __stopsys() __asm__("stopsys\n")
#define __stopexe() __asm__("stopexe\nnop\n")
#define __set0(x,y) __asm__("set0 "_ASMV(x)", #"_ASMD(y)"\n")
#define __set1(x,y) __asm__("set1 "_ASMV(x)", #"_ASMD(y)"\n")
//macros for clock setup
#define EASY_PDK_INIT_SYSCLOCK_8MHZ() {_clkmd=CLKMD_ENABLE_ILRC|CLKMD_ENABLE_IHRC|CLKMD_IHRC_DIV2;}
#define EASY_PDK_INIT_SYSCLOCK_4MHZ() {_clkmd=CLKMD_ENABLE_ILRC|CLKMD_ENABLE_IHRC|CLKMD_IHRC_DIV4;}
#define EASY_PDK_INIT_SYSCLOCK_2MHZ() {_clkmd=CLKMD_ENABLE_ILRC|CLKMD_ENABLE_IHRC|CLKMD_IHRC_DIV8;}
#define EASY_PDK_INIT_SYSCLOCK_1MHZ() {_clkmd=CLKMD_ENABLE_ILRC|CLKMD_ENABLE_IHRC|CLKMD_IHRC_DIV16;}
#define EASY_PDK_INIT_SYSCLOCK_512kHz() {_clkmd=CLKMD_ENABLE_ILRC|CLKMD_ENABLE_IHRC|CLKMD_IHRC_DIV32;}
//place holder for EASYPDK serial inserted from easypdkprog
#define EASY_PDK_SERIAL(sname) static const uint8_t sname[8] = {'F','P','S','E','R','I','A','L'}
//place holder for EASYPDK calibrations executed / replaced by easypdkprog
#define EASY_PDK_CALIBRATE_IHRC_H8(frequency,millivolt) \
__asm__( \
"and a, #'H' \n"\
"and a, #'8' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
"and a, #("#millivolt") \n"\
"and a, #("#millivolt">>8) \n"\
)
#define EASY_PDK_CALIBRATE_ILRC_L8(frequency,millivolt) \
__asm__( \
"and a, #'L' \n"\
"and a, #'8' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
"and a, #("#millivolt") \n"\
"and a, #("#millivolt">>8) \n"\
)
#define EASY_PDK_CALIBRATE_IHRC_H9(frequency,millivolt) \
__asm__( \
"and a, #'H' \n"\
"and a, #'9' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
"and a, #("#millivolt") \n"\
"and a, #("#millivolt">>8) \n"\
"and a, #0 \n"\
)
#define EASY_PDK_CALIBRATE_ILRC_L9(frequency,millivolt) \
__asm__( \
"and a, #'L' \n"\
"and a, #'9' \n"\
"and a, #("#frequency") \n"\
"and a, #("#frequency">>8) \n"\
"and a, #("#frequency">>16) \n"\
"and a, #("#frequency">>24) \n"\
"and a, #("#millivolt") \n"\
"and a, #("#millivolt">>8) \n"\
"and a, #0 \n"\
)
//__PDKCOMMON_H__
example main.c
#include <stdint.h>
#include "pms150c.h"
unsigned char _sdcc_external_startup(void)
{
EASY_PDK_INIT_SYSCLOCK_8MHZ(); //use 8MHz to save power
EASY_PDK_CALIBRATE_IHRC(8000000,3300); //tune SYSCLK to 8.0MHz @ 3.300V
return 0; //perform normal initialization
}
void main(void)
{
for(;;)
{
//YOUR CODE HERE
}
}