H8 evolved to H8S which evolved to H8SX which evolved into the RX line of Renesas. It’s not another RISC CPU, which usually would not matter at all as everyone uses C/C++ for programming microcontrollers (yes, I know, exceptions do exist), but for short code like the startup code, a little bit of assembler is still needed. Neither ARM nor MIPS nor SPARC assembler is fun to read or write.
Here some examples taken from a software I2C driver inspired from the I2C driver from MES:
C code:
union un_p6dr { /* union P6DR */
unsigned char BYTE; /* Byte Access */
struct { /* Bit Access */
unsigned char B7:1; /* Bit 7 */
unsigned char B6:1; /* Bit 6 */
unsigned char B5:1; /* Bit 5 */
unsigned char B4:1; /* Bit 4 */
unsigned char B3:1; /* Bit 3 */
unsigned char B2:1; /* Bit 2 */
unsigned char B1:1; /* Bit 1 */
unsigned char B0:1; /* Bit 0 */
} BIT;
};
#define P6DDR (*(volatile unsigned char *)0xFEE005) /* P6DDR Address*/
#define P6DR (*(volatile union un_p6dr *)0xFFFFD5) /* P6DR Address*/
#define I2CDDR P6DDR
#define SDA_MASK 0x01
#define SCL_MASK 0x02
#define SDA P6DR.BIT.B0
#define SCL P6DR.BIT.B1
void i2c_stop(void)
{
I2CDDR=SDA_MASK|SCL_MASK;
SDA=0;
SCL=1;
wait_us(4);
SDA=1;
}
AVR (8 bit RISC):
i2c_stop:
push r16
push r17
/* prologue: function */
/* frame size = 0 */
ldi r24,lo8(3)
sts -8187,r24
ldi r16,lo8(-43)
ldi r17,hi8(-43)
mov r30,r16
mov r31,r17
ld r24,Z
andi r24,lo8(127)
st Z,r24
ld r24,Z
ori r24,lo8(64)
st Z,r24
ldi r24,lo8(4)
ldi r25,hi8(4)
rcall wait_us
mov r30,r16
mov r31,r17
ld r24,Z
ori r24,lo8(-128)
st Z,r24
/* epilogue start */
pop r17
pop r16
ret
MIPS (32 bit):
i2c_stop:
.set nomips16
.frame $sp,24,$31 # vars= 0, regs= 2/0, args= 16, gp= 0
.mask 0x80010000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-24
li $3,3
li $2,16711680 # 0xff0000
sw $31,20($sp)
sw $16,16($sp)
li $16,16777216 # 0x1000000
sb $3,-8187($2)
lbu $2,-43($16)
li $3,-2 # 0xfffffffffffffffe
and $2,$2,$3
sb $2,-43($16)
lbu $3,-43($16)
li $4,4 # 0x4
ori $3,$3,0x2
sb $3,-43($16)
jal wait_us
nop
lbu $2,-43($16)
nop
ori $2,$2,0x1
sb $2,-43($16)
lw $31,20($sp)
lw $16,16($sp)
j $31
addiu $sp,$sp,24
H8/300H (16 bit):
_i2c_stop:
mov.w r6,@-r7
mov.w r7,r6
mov.w r4,@-r7
mov.b #3,r2l
mov.b r2l,@-8187:16
mov.w #-43,r4
bclr #0,@r4
bset #1,@r4
mov.w #4,r0
jsr @_wait_us
bset #0,@r4
mov.w @r7+,r4
mov.w @r7+,r6
rts
RX (16/32 bit):
_i2c_stop:
push.l r7
mov.L #0xfee005, r14
mov.L #0xffffd5, r7
mov.B #3, [r14]
mov.B [r7], r14
mov.L #4, r1
bclr #7, r14
mov.B r14, [r7]
mov.B [r7], r14
bset #6, r14
mov.B r14, [r7]
bsr _wait_us
mov.B [r7], r14
bset #7, r14
mov.B r14, [r7]
rtsd #4, r7-r7
x86_64 (64 bit):
i2c_stop:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movb $3, 16703493
movzbl 16777173, %eax
movl $4, %edi
andl $127, %eax
movb %al, 16777173
movzbl 16777173, %eax
orl $64, %eax
movb %al, 16777173
call wait_us
movzbl 16777173, %eax
orl $-128, %eax
movb %al, 16777173
addq $8, %rsp
ret
Easy to see why C wins this. ARM is not too bad too for a RISC CPU, but I have no example available. A notable oddity is that RX reversed bits (7,6 instead of 0,1). Not sure this is a bug or a feature.
Some more examples can be seen in the “99 bottles of beer” program examples under “A” like “assembler”.
It’s funny what makes one pick a microcontroller CPU. Since I don’t need performance or price for 1000 units, I can pick which assembler code looks easiest or nicest to me.
H8 and RX look like something readable and memorizable. In fact, H8 looks like Motorola M68k assembler. Both are said to be DEC PDP-11 related (see here and here)
Now this RX62N demo board is packed with interesting things and the price (US$99) is hard to beat. It also runs FreeRTOS since version 6.1, and Ethernet works too, which I have not yet working on my AKI-H8 board. And s JTAG based debugger is on-board too. And a graphics LCD. I think it’s a bargain similar to the STM32VLDiscovery or the STM8SDiscovery for each US$11.
Now let’s see how long Digikey takes to deliver them to Japan.
Update: 4 days.