├── xmodem.h ├── led.h ├── sleep.h ├── led.c ├── isrhdl.s ├── pmh4.h ├── test.h ├── sleep.c ├── console.c ├── ringbuffer.h ├── common.h ├── adc.h ├── Makefile ├── linkscript.x ├── common.c ├── README.md ├── adc.c ├── lpc.c ├── pmh4.c ├── ringbuffer.c ├── irqs.h ├── LICENSE ├── gpio.h ├── main.c ├── startup.s ├── test.c ├── serial.h ├── xmodem.c ├── power.h ├── lpc.h ├── serial.c └── vectors.s /xmodem.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef XMODEM_H 3 | #define XMODEM_H 4 | 5 | void xmodem_receive(); 6 | 7 | #endif /* XMODEM_H */ 8 | -------------------------------------------------------------------------------- /led.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LED_H 3 | #define LED_H 4 | 5 | void led_caps(short state); 6 | void led_num(short state); 7 | 8 | #endif /* LED_H */ 9 | -------------------------------------------------------------------------------- /sleep.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SLEEP_H 3 | #define SLEEP_H 4 | 5 | void sleep1s(); 6 | void sleep(int seconds); 7 | 8 | /* 1useconds => real 9useconds */ 9 | void usleep(int useconds); 10 | 11 | #endif /* SLEEP_H */ 12 | -------------------------------------------------------------------------------- /led.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gpio.h" 3 | #include "led.h" 4 | 5 | void led_caps(short state) { 6 | if (state) 7 | P2DR &= ~(1 << 7); 8 | else 9 | P2DR |= (1 << 7); 10 | } 11 | 12 | void led_num(short state) { 13 | if (state) 14 | P2DR &= ~(1 << 5); 15 | else 16 | P2DR |= (1 << 5); 17 | } 18 | -------------------------------------------------------------------------------- /isrhdl.s: -------------------------------------------------------------------------------- 1 | .h8300s 2 | 3 | .global _unused_isr 4 | .global _rxi1_isr 5 | .global _eri1_isr 6 | .extern _rxi1_irq 7 | .extern _eri1_irq 8 | .section .text 9 | 10 | _unused_isr: 11 | rte 12 | 13 | _eri1_isr: 14 | jsr @_eri1_irq 15 | rte 16 | 17 | _rxi1_isr: 18 | jsr @_rxi1_irq 19 | rte 20 | .end 21 | -------------------------------------------------------------------------------- /pmh4.h: -------------------------------------------------------------------------------- 1 | 2 | /* data direction must be set to output seperate*/ 3 | 4 | /* pin on the port */ 5 | #define XP_CLK 0 6 | #define XP_DATA 1 7 | #define XP_LE 2 8 | #define XP_OE 3 9 | #define XP_PORT_DATA P2DR 10 | #define XP_PORT_DIRECTION P2DDR 11 | 12 | void send_pmh(int sleep_us, char *message, int len); 13 | -------------------------------------------------------------------------------- /test.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef TEST_H 3 | #define TEST_H 4 | 5 | #include "common.h" 6 | 7 | void print_size_u8(); 8 | void print_size_u16(); 9 | void print_size_u32(); 10 | void print_size_int(); 11 | 12 | void print_size_pointer(); 13 | void dump_memory(uint8_t *start, int len); 14 | 15 | void test_ringbuffer(); 16 | #endif /* TEST_H */ 17 | -------------------------------------------------------------------------------- /sleep.c: -------------------------------------------------------------------------------- 1 | 2 | #include "sleep.h" 3 | 4 | void sleep1s() { 5 | for (unsigned int j=0; j<65535; j++) 6 | ; 7 | for (unsigned int j=0; j<65535; j++) 8 | ; 9 | } 10 | 11 | void sleep(int seconds) { 12 | while(seconds-- > 0) 13 | sleep1s(); 14 | } 15 | 16 | /* 1useconds => real 9useconds */ 17 | void usleep(int useconds) { 18 | while(useconds-- > 0) 19 | ; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /console.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "serial.h" 4 | 5 | static char line_buffer[128]; 6 | 7 | /* set line and length. line includes \n*/ 8 | int getline(char **line, int *length) { 9 | for (int i=0; i < ARRAY_SIZE(line_buffer); i++) { 10 | while (uart_getc(&line_buffer[i])) 11 | ; 12 | 13 | if (line_buffer[i] == '\n') { 14 | *line = line_buffer; 15 | *length = i; 16 | return 0; 17 | } else if (line_buffer[i] == '\0') { 18 | return 1; 19 | } 20 | } 21 | return -1; 22 | } 23 | -------------------------------------------------------------------------------- /ringbuffer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RINGBUFFER_H 3 | #define RINGBUFFER_H 4 | 5 | #include "common.h" 6 | 7 | struct ringbuffer_t { 8 | uint8_t *start; 9 | uint8_t *last; 10 | uint8_t *read; 11 | uint8_t *write; 12 | uint8_t status; 13 | }; 14 | 15 | #define BUFFER_EMPTY 1; 16 | #define RING_OVERFLOW BIT(0) 17 | 18 | int ringbuffer_read(struct ringbuffer_t *ring, uint8_t *read); 19 | int ringbuffer_write(struct ringbuffer_t *ring, uint8_t write); 20 | inline int ring_is_readable(struct ringbuffer_t *ring); 21 | 22 | #endif /* RINGBUFFER_H */ 23 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef COMMON_H 3 | #define COMMON_H 4 | 5 | typedef unsigned char uint8_t; 6 | typedef unsigned int uint16_t; 7 | typedef unsigned long uint32_t; 8 | typedef unsigned long size_t; 9 | 10 | #ifndef ARRAY_SIZE 11 | #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) 12 | #endif 13 | 14 | #define BIT(x) (1 << x) 15 | 16 | size_t strlen(const char *s); 17 | void *memset(void *s, int c, size_t n); 18 | int strcmp(const char *s1, const char *s2); 19 | int strncmp(const char *s1, const char *s2, size_t n); 20 | 21 | #endif /* COMMON_H */ 22 | -------------------------------------------------------------------------------- /adc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ADC_H 3 | #define ADC_H 4 | 5 | #include "common.h" 6 | 7 | /* have to add adc because of dublicate register name DACR for PWMX and ADC */ 8 | #define ADC_DADR0 (*(volatile unsigned char*) (0xfffff8)) /* D/A data register 0 */ 9 | #define ADC_DADR1 (*(volatile unsigned char*) (0xfffff9)) /* D/A data register 1 */ 10 | #define ADC_DACR (*(volatile unsigned char*) (0xfffffa)) /* D/A control register */ 11 | int enable_dac(uint8_t channel, uint8_t enable); 12 | void set_dac(uint8_t channel, uint8_t value); 13 | 14 | #endif /* ADC_H */ 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | COPT = -c -ms -Wall --std=c99 2 | ASMOPT = -o 3 | 4 | OBJ = test.o common.o ringbuffer.o led.o sleep.o serial.o pmh4.o xmodem.o console.o main.o startup.o vectors.o isrhdl.o adc.o 5 | 6 | AS := h8300-hms-as 7 | GCC := h8300-hms-gcc 8 | OBJCOPY := h8300-hms-objcopy 9 | OBJDUMP := h8300-hms-objdump 10 | 11 | blinkled.mot: blinkled 12 | $(OBJCOPY) -O srec blinkled blinkled.mot 13 | 14 | blinkled: $(OBJ) 15 | $(GCC) -ms -nostdlib -T linkscript.x -o $@ $^ 16 | 17 | %.o: %.c 18 | $(GCC) ${COPT} $< 19 | 20 | %.o: %.s 21 | $(AS) ${ASMOPT} $@ $< 22 | 23 | clean: 24 | rm -f blinkled blinkled.srec *.o 25 | -------------------------------------------------------------------------------- /linkscript.x: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(h8300:h8300s) 2 | ENTRY(_startp) 3 | 4 | 5 | MEMORY 6 | { 7 | rom (rx) : ORIGIN = 0x0, LENGTH = 128K 8 | ram (!rx): ORIGIN = 0xffe080, LENGTH = 3968 9 | tiny (!rx): ORIGIN = 0xffff00, LENGTH = 128 10 | } 11 | 12 | SECTIONS 13 | { 14 | .vectors 0x0 : { *(.vectors) } >rom 15 | .text 0x200 : { 16 | *(.text); 17 | *(.rodata); 18 | _etext = ALIGN(4); 19 | } >rom 20 | 21 | .data : { 22 | _rom_data = LOADADDR(.data); 23 | _data = .; 24 | *(.data); 25 | _edata = .; 26 | } >ram AT>rom 27 | 28 | .bss : { 29 | _bss = .; 30 | *(.bss); 31 | _ebss = .; 32 | } >ram 33 | 34 | .stack : { 35 | _stack_last = .; 36 | . += 0x80; 37 | _stack = .; 38 | _stack_first = .; 39 | *(.stack) 40 | } >ram 41 | } 42 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | 4 | size_t strlen(const char *s) { 5 | size_t ret = 0; 6 | while(*s++) 7 | ret++; 8 | return ret; 9 | } 10 | 11 | /* TODO: replace this by asm routine */ 12 | void *memset(void *s, int c, size_t n) { 13 | uint8_t *tmp = s; 14 | while (n--) 15 | *(tmp++) = c; 16 | return s; 17 | } 18 | 19 | int strcmp(const char *s1, const char *s2) { 20 | while (*s1 && *s2) { 21 | if (*s1 != *s2) { 22 | return 1; 23 | } 24 | s1++; 25 | s2++; 26 | } 27 | if (*s1 == 0 && *s2 == 0) { 28 | return 0; 29 | } 30 | return 1; 31 | } 32 | 33 | int strncmp(const char *s1, const char *s2, size_t n) { 34 | while (n--) { 35 | if (*s1 == 0 && *s2 == 0) { 36 | return 0; 37 | } else if (*s1 != *s2) { 38 | return 1; 39 | } 40 | s1++; 41 | s2++; 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # open source embedded controller firmware for H8/S 2161 [built-in Thinkpad T40] 2 | 3 | ## how to compile 4 | Because of time pressure I'm still using the debian package gcc-h8300-hms/binutils-h8300-hms 5 | On debian jessy 6 | - gcc-h8300-hms 7 | - binutils-h8300-hms 8 | - build-essentials 9 | 10 | Just do make 11 | 12 | ## how to flash the firmware to a device? 13 | At the moment the only possible way to flash this firmware is using the ROM loader. 14 | To access the ROM loader you must change solder several pins to enter it. 15 | Pins: P90, P91, P92, mode0, mode1 16 | 17 | After you have activated the boot loader mode, you can use the official renesas 18 | flash kit. It's possible to use open source flash software, but this wasn't done 19 | because of time pressure. 20 | 21 | Use blinkled.mot with reneases flash tool kit 22 | -------------------------------------------------------------------------------- /adc.c: -------------------------------------------------------------------------------- 1 | 2 | #include "adc.h" 3 | #include "power.h" 4 | #include "common.h" 5 | 6 | static void disable_unused_pwm_module() { 7 | /* when no output channel is active disable module */ 8 | if (!(ADC_DACR >> 5)) { 9 | MSTPCRH |= MSTPCRH_DAC; 10 | } 11 | } 12 | 13 | int enable_dac(uint8_t channel, uint8_t enable) { 14 | /* out of range */ 15 | if (channel > 1) 16 | return -1; 17 | 18 | channel &= 0x3; 19 | 20 | if (enable) { 21 | /* pull dac out of halt state */ 22 | MSTPCRH &= ~MSTPCRH_DAC; 23 | 24 | ADC_DACR |= channel << 6; 25 | } else { 26 | ADC_DACR &= ~(channel << 6); 27 | } 28 | 29 | disable_unused_pwm_module(); 30 | 31 | return 0; 32 | } 33 | 34 | void set_dac(uint8_t channel, uint8_t value) { 35 | /* when module is disable dont do anything */ 36 | if (MSTPCRH & MSTPCRH_DAC) 37 | return; 38 | 39 | /* the channel can be still disabled but register writes are ok */ 40 | 41 | switch (channel) { 42 | case 0: 43 | ADC_DADR0 = value; 44 | break; 45 | case 1: 46 | ADC_DADR1 = value; 47 | break; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lpc.c: -------------------------------------------------------------------------------- 1 | 2 | #include "lpc.h" 3 | #include "power.h" 4 | #include "common.h" 5 | 6 | void enable_lpc(int channel) { 7 | /* put out of module disable */ 8 | MSTPCRH &= ~MSTPCRL_LPC; 9 | 10 | } 11 | 12 | 13 | /* start up process 14 | * chanenl3 set address 15 | * set enable channel (1,2 or 3) 16 | * set if (GA20E, PMEE, LSMIE, and LSCIE) 17 | * set if (SDWNE, IEDIR). 18 | * as a precaution, clear the interrupt flags (LRST, SDWN, ABRT, OBF). Read IDR or TWR15 to clear IBF. 19 | * Set interrupt enable bits (IBFIE3 to IBFIE1, ERRIE) as necessary. 20 | */ 21 | 22 | 23 | 24 | 25 | /* only channel 3 has a variable address. channel 1 & 2 has fixed addresses */ 26 | void lpc_set_channel3_address(uint16_t address, uint8_t twr_enable) { 27 | uint8_t val; 28 | 29 | LPC_LADR3H = address >> 8; 30 | 31 | /* lower 8 bit */ 32 | val = (address & 0xff); 33 | 34 | /* bit 2 is reseved - recommend to write only 0 into */ 35 | val &= ~(1 << 2); 36 | 37 | /* bit 0 is twr */ 38 | if (twr_enable) 39 | val |= (1 << 0); 40 | else 41 | val &= ~(1 << 0); 42 | 43 | LPC_LADR3L = val; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /pmh4.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gpio.h" 3 | #include "sleep.h" 4 | #include "pmh4.h" 5 | 6 | /* send a simple hello to the board 7 | * 1 / (sleep_us*2) = frequency. 8 | */ 9 | 10 | 11 | /* bit bang the XP (extra protocol? :) 12 | * 13 | * The protocol use a data and a clock line. It's unidirectional. 14 | * Transmit one bit per clock cycle. 15 | * After all bytes are send, shortly pulse the LE pin to high. 16 | * OE is Low as long we are talking to the chip 17 | */ 18 | void send_pmh(int sleep_us, char *message, int len) { 19 | /* OE must be low all the time */ 20 | XP_PORT_DATA &= ~(1 << XP_OE); 21 | 22 | /* message loop - transmit byte by byte */ 23 | for (short i=0; i < len; i++) { 24 | 25 | /* byte loop - transmit bit by bit */ 26 | for (short j=7; j >= 0; j--) { 27 | XP_PORT_DATA &= ~(1 << XP_CLK); /* clk low */ 28 | 29 | if (message[i] & (1 << j)) { 30 | XP_PORT_DATA |= (1 << XP_DATA); 31 | } else { 32 | XP_PORT_DATA &= ~(1 << XP_DATA); 33 | } 34 | usleep(sleep_us); 35 | 36 | XP_PORT_DATA |= (1 << XP_CLK); /* clk high */ 37 | usleep(sleep_us); 38 | } 39 | } 40 | 41 | /* latch enable is an end of transmission latch. Only pulsed shortly */ 42 | usleep(1); 43 | XP_PORT_DATA &= ~(1 << XP_LE); 44 | usleep(1); 45 | XP_PORT_DATA |= (1 << XP_LE); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /ringbuffer.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "ringbuffer.h" 4 | 5 | static inline void increase_read_pointer(struct ringbuffer_t *ring) { 6 | if (ring->read == ring->last) 7 | ring->read = ring->start; 8 | else 9 | ring->read++; 10 | } 11 | 12 | static inline void increase_write_pointer(struct ringbuffer_t *ring) { 13 | volatile void *next_element; 14 | if (ring->write == ring->last) 15 | next_element = ring->start; 16 | else 17 | next_element = ring->write + 1; 18 | 19 | /* check if ringbuffer overflows */ 20 | if (ring->read == next_element) { 21 | /* overflow - we will loose one slot here, because of implementation */ 22 | ring->status |= RING_OVERFLOW; 23 | if (next_element == ring->last) 24 | ring->read = ring->start; 25 | else 26 | ring->read++; 27 | } 28 | 29 | ring->write = (void *)next_element; 30 | *ring->write = 0; 31 | } 32 | 33 | int ringbuffer_read(struct ringbuffer_t *ring, uint8_t *read) { 34 | if (!ring_is_readable(ring)) 35 | return -BUFFER_EMPTY; 36 | *read = *ring->read; 37 | increase_read_pointer(ring); 38 | return 0; 39 | } 40 | 41 | int ringbuffer_write(struct ringbuffer_t *ring, uint8_t write) { 42 | *ring->write = write; 43 | increase_write_pointer(ring); 44 | return 0; 45 | } 46 | 47 | inline int ring_is_readable(struct ringbuffer_t *ring) { 48 | return (ring->read == ring->write) ? 0 : 1; 49 | } 50 | -------------------------------------------------------------------------------- /irqs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef IRQS_H 3 | #define IRQS_H 4 | 5 | #define ICRA (*(volatile unsigned char*) (0xfffee8)) /* Interupt control register A */ 6 | #define ICRB (*(volatile unsigned char*) (0xfffee9)) /* Interupt control register B */ 7 | #define ICRC (*(volatile unsigned char*) (0xfffeea)) /* Interupt control register C */ 8 | #define ISR (*(volatile unsigned char*) (0xfffeeb)) /* IRQ status register */ 9 | #define ISCRH (*(volatile unsigned char*) (0xfffeec)) /* IRQ sense control register H */ 10 | #define ISCRL (*(volatile unsigned char*) (0xfffeed)) /* IRQ sense control register L */ 11 | #define WUEMRB (*(volatile unsigned char*) (0xfffe44)) /* Wakeup event interrupt mask register B */ 12 | #define ABRKCR (*(volatile unsigned char*) (0xfffef4)) /* Address break control register */ 13 | #define BARA (*(volatile unsigned char*) (0xfffef5)) /* Break address register A */ 14 | #define BARB (*(volatile unsigned char*) (0xfffef6)) /* Break address register B */ 15 | #define BARC (*(volatile unsigned char*) (0xfffef7)) /* Break address register C */ 16 | #define IER (*(volatile unsigned char*) (0xffffc2)) /* Interrupt enable register */ 17 | #define KMIMR (*(volatile unsigned char*) (0xfffff1)) /* Keyboard matrix interrupt register 6 */ 18 | #define KMIMRA (*(volatile unsigned char*) (0xfffff2)) /* Keyboard matrix interrupt register A */ 19 | 20 | inline void disable_irqs() { 21 | __asm__ __volatile__("\torc #0x80,ccr\n":::"cc"); 22 | } 23 | 24 | inline void enable_irqs() { 25 | __asm__ __volatile__("\tandc #0x7f,ccr\n":::"cc"); 26 | } 27 | 28 | #endif /* IRQS_H */ 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Alexander Couzens 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | // 6 | // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | // 8 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | // 10 | // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | // 12 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | // 14 | -------------------------------------------------------------------------------- /gpio.h: -------------------------------------------------------------------------------- 1 | 2 | #define P1DDR (*(volatile unsigned char*) (0xffffb0)) /* Port 1 Data Direction Register */ 3 | #define P2DDR (*(volatile unsigned char*) (0xffffb1)) /* Port 2 Data Direction Register */ 4 | #define P1DR (*(volatile unsigned char*) (0xffffb2)) /* Port 1 Data Register */ 5 | #define P2DR (*(volatile unsigned char*) (0xffffb3)) /* Port 2 Data Register */ 6 | #define P3DDR (*(volatile unsigned char*) (0xffffb4)) /* Port 3 Data Direction Register */ 7 | #define P4DDR (*(volatile unsigned char*) (0xffffb5)) /* Port 4 Data Direction Register */ 8 | #define P3DR (*(volatile unsigned char*) (0xffffb6)) /* Port 3 Data Register */ 9 | #define P4DR (*(volatile unsigned char*) (0xffffb7)) /* Port 4 Data Register */ 10 | #define P5DDR (*(volatile unsigned char*) (0xffffb8)) /* Port 5 Data Direction Register */ 11 | #define P6DDR (*(volatile unsigned char*) (0xffffb9)) /* Port 6 Data Direction Register */ 12 | #define P5DR (*(volatile unsigned char*) (0xffffba)) /* Port 5 Data Register */ 13 | #define P6DR (*(volatile unsigned char*) (0xffffbb)) /* Port 6 Data Register */ 14 | #define PBODR (*(volatile unsigned char*) (0xffffbc)) /* Port B Output Direction Register */ 15 | #define P8DDR (*(volatile unsigned char*) (0xffffbd)) /* Port 8 Data Direction Register (write) */ 16 | #define PBPIN (*(volatile unsigned char*) (0xffffbd)) /* Port B ????????????? (read) */ 17 | #define PBDDR (*(volatile unsigned char*) (0xffffbe)) /* Port B Data Direction Register (write) */ 18 | #define P7PIN (*(volatile unsigned char*) (0xffffbe)) /* Port 7 ????????????? (read) */ 19 | #define P8DR (*(volatile unsigned char*) (0xffffbf)) /* Port 8 Data Register */ 20 | #define P9DDR (*(volatile unsigned char*) (0xffffc0)) /* Port 9 Data Direction Register */ 21 | #define P9DR (*(volatile unsigned char*) (0xffffc1)) /* Port 9 Data Register */ 22 | #define PDDDR (*(volatile unsigned char*) (0xffff4f)) /* Port D Data Direction Register */ 23 | #define PDODR (*(volatile unsigned char*) (0xffff4d)) /* Port D Data Register */ 24 | 25 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "sleep.h" 4 | #include "serial.h" 5 | #include "power.h" 6 | #include "gpio.h" 7 | 8 | #include "adc.h" 9 | #include "led.h" 10 | #include "pmh4.h" 11 | #include "irqs.h" 12 | #include "test.h" 13 | 14 | void power_board() { 15 | /* !mainoff */ 16 | P2DR |= (1 << 4); 17 | 18 | /* -KBRC */ 19 | /* FAN On */ 20 | /* -batlow */ 21 | P4DR |= (1 << 0) | (1 << 4) | (1 << 3); 22 | 23 | /* -pwrsw_h8s */ 24 | P9DR |= (1 << 5); 25 | sleep(2); 26 | P9DR &= ~(1 << 5); 27 | sleep(2); 28 | P9DR |= (1 << 5); 29 | } 30 | 31 | int main() { 32 | P2DDR = 0xf0; /* -MAINOFF -LEDNUMPAD -BAYLED -LEDCAPSLOCK */ 33 | P4DDR = ((1 << 0) | (1 << 3) | 1 << 4); /* -KBRC -BATLOW FANON */ 34 | P9DDR = (1 << 5); 35 | 36 | P8DDR = (1 << 1) | (1 << 4); /* TXD1 output */ 37 | 38 | led_caps(0); 39 | led_num(0); 40 | for(int i=0; i<3; i++) { 41 | led_caps(1); 42 | sleep(1); 43 | led_caps(0); 44 | sleep(1); 45 | } 46 | 47 | int ret = setup_serial(B9600, 0); 48 | while(ret) { 49 | led_num(1); 50 | } 51 | 52 | print_size_u8(); 53 | print_size_u16(); 54 | print_size_u32(); 55 | print_size_int(); 56 | print_size_pointer(); 57 | dump_memory((void *)0xffe080, 3*32); 58 | 59 | led_num(0); 60 | led_caps(0); 61 | enable_dac(0, 1); 62 | enable_dac(1, 1); 63 | set_dac(0, 120); 64 | set_dac(1, 120); 65 | uart_print_rx_ringbuffer(); 66 | uart_puts("TX\n"); 67 | uart_print_tx_ringbuffer(); 68 | test_ringbuffer(); 69 | 70 | for(int i=0; i<5; i++) { 71 | led_num(1); 72 | sleep(1); 73 | led_num(0); 74 | sleep(1); 75 | } 76 | 77 | power_board(); 78 | uart_enable_rx(); 79 | enable_irqs(); 80 | 81 | while(1) { 82 | uart_puts("\r\nyip\r\n"); 83 | while (uart_readable()) { 84 | char c; 85 | uart_puts("rd:"); 86 | if (uart_getc(&c)) 87 | break; 88 | uart_putc(c); 89 | } 90 | 91 | debug_irq(); 92 | led_caps(1); 93 | sleep(1); 94 | 95 | led_caps(0); 96 | sleep(1); 97 | } 98 | uart_puts("NEVER"); 99 | uart_puts("NEVER"); 100 | uart_puts("NEVER"); 101 | uart_puts("NEVER"); 102 | } 103 | -------------------------------------------------------------------------------- /startup.s: -------------------------------------------------------------------------------- 1 | ; Startup Code for H8S 2161 2 | ; Original from Johan Henning 3 | ; Little modifications by Johann Gysin 4 | ; Very little modifications by Alexander Couzens 5 | ; 29.06.2015 6 | ; 7 | .h8300s 8 | .section .text 9 | .global _startp 10 | .global _startm 11 | 12 | .extern _rom_data ; ROM copy of initialized data segment 13 | .extern _data ; beginning of initialized data segment 14 | .extern _edata ; end of initialized data segment 15 | .extern _bss ; beginning of uninitialized data segment 16 | .extern _ebss ; end of uninitialised data segment 17 | .extern _stack ; stack segment 18 | 19 | _startp: 20 | ; C runtime start from power-on reset 21 | ; mov.w #0x0001, r2 22 | ; mov.l #0x0000, er3 23 | ; mov.w r2, @er3 ; A value of 1 in po_reset will denote power-on-reset 24 | ; jmp _continue ; 25 | 26 | _startm: 27 | ;; C runtime start from manual reset 28 | ; mov.w #0x0000, r2 29 | ; mov.l #0x0000, er3 30 | ; mov.w r2, @er3 ; A value of 0 in po_reset will denote manual-reset 31 | 32 | _continue: 33 | ; Set stack pointer 34 | mov.l #_stack,sp 35 | 36 | _start2: 37 | mov.l #_data,er0 ; start of RAM .data section 38 | mov.l #_edata,er1 ; end of RAM .data section 39 | mov.l #_rom_data,er2 ; location of ROM .data storage 40 | data_init_loop: 41 | mov.w @er2,r3 ; get next word 42 | mov.w r3,@er0 ; move it 43 | adds #2,er2 ; increment source ptr 44 | adds #2,er0 ; increment destination ptr 45 | cmp.l er1,er0 ; test for done 46 | blo data_init_loop 47 | 48 | ; zero out .bss ram data area 49 | mov.l #_bss,er0 ; start of RAM .bss section 50 | mov.l #_ebss,er1 ; end of RAM .bss section 51 | mov.w #0,r2 52 | bss_init_loop: 53 | mov.w r2,@er0 ; clear memory 54 | adds #2,er0 ; increment ptr 55 | cmp.l er1,er0 ; test for done 56 | blo bss_init_loop 57 | 58 | ; initialize stack area to 'DEAD' to track stack usage 59 | mov.l #_stack_last,er0 ; beginning of RAM .stack section 60 | mov.l #_stack_first,er1 ; end of RAM .stack section 61 | mov.w #0xDEAD,r2 ; marker indicating unused stack 62 | stack_init_loop: 63 | mov.w r2,@er0 ; store marker 64 | adds #2,er0 ; increment ptr 65 | cmp.l er1,er0 ; test for done 66 | blo stack_init_loop 67 | 68 | ; call main 69 | jmp @_main 70 | .end 71 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | 2 | #include "test.h" 3 | 4 | #include "common.h" 5 | #include "serial.h" 6 | #include "ringbuffer.h" 7 | 8 | void print_size_u8() { 9 | int i = sizeof(uint8_t); 10 | uart_puts("Size of 8"); 11 | while (i--) { 12 | uart_putc('Q'); 13 | } 14 | } 15 | 16 | void print_size_u16() { 17 | int i = sizeof(uint16_t); 18 | uart_puts("Size of 16"); 19 | while (i--) { 20 | uart_putc('W'); 21 | } 22 | } 23 | 24 | void print_size_u32() { 25 | int i = sizeof(uint32_t); 26 | uart_puts("Size of 32"); 27 | while (i--) { 28 | uart_putc('E'); 29 | } 30 | } 31 | 32 | void print_size_pointer() { 33 | int i = sizeof(uint32_t *); 34 | uart_puts("Size of 32p"); 35 | while (i--) { 36 | uart_putc('R'); 37 | } 38 | } 39 | 40 | void print_size_int() { 41 | int i = sizeof(int); 42 | uart_puts("Size of int"); 43 | while (i--) { 44 | uart_putc('T'); 45 | } 46 | } 47 | 48 | void dump_memory(uint8_t *start, int len) { 49 | uart_puts("memory dump\r\n"); 50 | for (int i=0; i < len; i++) { 51 | uart_put_u8(*start); 52 | start++; 53 | if(i % 32 == 0) { 54 | uart_putc('\r'); 55 | uart_putc('\n'); 56 | } else if (i % 4 == 0) { 57 | uart_putc(' '); 58 | } 59 | } 60 | uart_puts("\r\nend\r\n"); 61 | } 62 | 63 | static uint8_t test_buffer[8]; 64 | 65 | static struct ringbuffer_t testring = { 66 | .start = test_buffer, 67 | .last = test_buffer + 8 - 1, 68 | .read = test_buffer, 69 | .write = test_buffer, 70 | .status = 0, 71 | }; 72 | 73 | static void print_ringbuffer(struct ringbuffer_t *ring) { 74 | uart_puts("\r\n=ringbuffer"); 75 | uart_puts("\r\npo "); 76 | uart_put_pointer(ring); 77 | uart_puts("\r\nst "); 78 | uart_put_pointer(ring->start); 79 | uart_puts("\r\nla "); 80 | uart_put_pointer(ring->last); 81 | uart_puts("\r\nrd "); 82 | uart_put_pointer(ring->read); 83 | uart_puts("\r\nwr "); 84 | uart_put_pointer(ring->write); 85 | } 86 | 87 | void test_ringbuffer() { 88 | uint16_t ret = 0; 89 | char ch = 0; 90 | uart_puts("ringbuffer test\r\n"); 91 | uart_puts("\r\nringbuffer is empty. Check is_readable\r\n"); 92 | uart_puts("should be 0000. is : "); 93 | uart_put_u16(ring_is_readable(&testring)); 94 | uart_puts("\r\n"); 95 | uart_puts("writing 4 bytes into ringbuffer (1234)\r\n"); 96 | ringbuffer_write(&testring, '1'); 97 | ringbuffer_write(&testring, '2'); 98 | ringbuffer_write(&testring, '3'); 99 | ringbuffer_write(&testring, '4'); 100 | 101 | print_ringbuffer(&testring); 102 | 103 | uart_puts("check if ring is readable\r\n"); 104 | uart_puts("check readable : "); 105 | uart_put_u16(ring_is_readable(&testring)); 106 | uart_puts("\r\n"); 107 | 108 | uart_puts("read out all avaiable bytes until ring isnt readable\r\n"); 109 | while (ring_is_readable(&testring)) { 110 | uart_puts("read return code "); 111 | ret = ringbuffer_read(&testring, &ch); 112 | uart_put_u16(ret); 113 | uart_puts(" char is : "); 114 | uart_putc(ch); 115 | uart_puts("\r\n"); 116 | } 117 | uart_puts("end reading variables\r\n"); 118 | uart_puts("try to read even when ring isnt readable"); 119 | uart_puts("read return code "); 120 | ret = ringbuffer_read(&testring, &ch); 121 | uart_put_u16(ret); 122 | uart_puts(" char is : "); 123 | uart_putc(ch); 124 | uart_puts("\r\n"); 125 | } 126 | -------------------------------------------------------------------------------- /serial.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SERIAL_H 3 | #define SERIAL_H 4 | 5 | #include "common.h" 6 | 7 | #define SMR_0 (*(volatile unsigned char*) (0xffffd8)) /* Serial 0 Mode */ 8 | #define BRR_0 (*(volatile unsigned char*) (0xffffd9)) /* Serial 0 Bit Rate */ 9 | #define SCR_0 (*(volatile unsigned char*) (0xffffda)) /* Serial 0 Serial Control */ 10 | #define TDR_0 (*(volatile unsigned char*) (0xffffdb)) /* Serial 0 Transmit Data */ 11 | #define SSR_0 (*(volatile unsigned char*) (0xffffdc)) /* Serial 0 Serial Status */ 12 | #define RDR_0 (*(volatile unsigned char*) (0xffffdd)) /* Serial 0 Receive Data */ 13 | #define SCMR_0 (*(volatile unsigned char*) (0xffffde)) /* Serial 0 Smart Card Mode */ 14 | 15 | #define SMR_1 (*(volatile unsigned char*) (0xffff88)) /* Serial 1 Mode */ 16 | #define BRR_1 (*(volatile unsigned char*) (0xffff89)) /* Serial 1 Bit Rate */ 17 | #define SCR_1 (*(volatile unsigned char*) (0xffff8a)) /* Serial 1 Serial Control */ 18 | #define TDR_1 (*(volatile unsigned char*) (0xffff8b)) /* Serial 1 Transmit Data */ 19 | #define SSR_1 (*(volatile unsigned char*) (0xffff8c)) /* Serial 1 Serial Status */ 20 | #define RDR_1 (*(volatile unsigned char*) (0xffff8d)) /* Serial 1 Receive Data */ 21 | #define SCMR_1 (*(volatile unsigned char*) (0xffff8e)) /* Serial 1 Smart Card Mode */ 22 | 23 | /* SCI SCL register bit definitions */ 24 | #define SCR_TIE (1 << 7) 25 | #define SCR_RIE (1 << 6) 26 | #define SCR_TE (1 << 5) 27 | #define SCR_RE (1 << 4) 28 | #define SCR_MPIE (1 << 3) 29 | #define SCR_TEIE (1 << 2) 30 | #define SCR_CKE1 (1 << 1) 31 | #define SCR_CKE0 (1 << 0) 32 | 33 | /* SCI SMR register bit definitions */ 34 | #define SMR_C_nA (1 << 7) /* communication mode. 0 -> async, 1 -> clocked sync */ 35 | #define SMR_CHR (1 << 6) /* character lenght 0 -> 8bits, 1 -> 7bits */ 36 | #define SMR_PE (1 << 5) /* parity enable */ 37 | #define SMR_O_nE (1 << 4) /* parity mode 0 -> even, 1 -> odd */ 38 | #define SMR_STOP (1 << 3) /* parirty stop bit lenght 0 -> 1 stop bits, 1 -> 2 stop bits*/ 39 | #define SMR_MP (1 << 2) /* multiprocess mode enable */ 40 | #define SMR_CKS1 (1 << 1) /* see baudrate calculation */ 41 | #define SMR_CKS0 (1 << 0) /* see baudrate calculation */ 42 | 43 | /* SCI SSR register bit definitions */ 44 | #define SSR_TDRE (1 << 7) /* transmit data register empty */ 45 | #define SSR_RDRF (1 << 6) /* receive data register full */ 46 | #define SSR_ORER (1 << 5) /* Overrun Error */ 47 | #define SSR_FER (1 << 4) /* Framing Error */ 48 | #define SSR_PER (1 << 3) /* Parity Error */ 49 | #define SSR_TEND (1 << 2) /* Transmit End */ 50 | #define SSR_MPB (1 << 1) /* Multiprocessor Bit */ 51 | #define SSR_MPBT (1 << 0) /* Multiprocessor Bit Transfer */ 52 | 53 | 54 | enum e_baudrate { 55 | B4800 = 0, 56 | B9600, 57 | B19200, 58 | B31250, 59 | B38400, 60 | }; 61 | 62 | 63 | void debug_irq(); 64 | void rxi1_irq(); 65 | void eri1_irq(); 66 | void uart_read_poll(); 67 | void uart_putc(const char c); 68 | void uart_puts(const char *str); 69 | int uart_getc(char *ch); 70 | int uart_readable(); 71 | int setup_serial(enum e_baudrate baudrate, short enable_interupts); 72 | void uart_enable_rx(); 73 | 74 | void uart_put_u8(uint8_t value); 75 | void uart_put_u16(uint16_t value); 76 | void uart_put_u32(uint32_t value); 77 | void uart_put_pointer(void *value); 78 | 79 | void uart_print_rx_ringbuffer(); 80 | void uart_print_tx_ringbuffer(); 81 | 82 | extern uint8_t rdr; 83 | 84 | #endif /* SERIAL_H */ 85 | -------------------------------------------------------------------------------- /xmodem.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "sleep.h" 4 | #include "xmodem.h" 5 | 6 | #define WAITING_TO_START 0 7 | #define WAITING_FOR_SEQ 1 8 | #define WAITING_FOR_CMPL 2 9 | #define RECEIVING_DATA 3 10 | #define WAITING_FOR_CRC 4 11 | #define WAITING_FOR_SOH 5 12 | #define DROP_UNTIL_SOH_ACK 6 13 | #define DROP_UNTIL_SOH_NAK 7 14 | #define STOP 8 15 | 16 | #define XMODEM_SOH 0x01 /* Start Of Header */ 17 | #define XMODEM_EOT 0x04 /* End Of Transmission */ 18 | #define XMODEM_ACK 0x06 /* Acknowledge (positive) */ 19 | #define XMODEM_DLE 0x10 /* Data Link Escape */ 20 | #define XMODEM_XON 0x11 /* Transmit On */ 21 | #define XMODEM_XOFF 0x13 /* Transmit Off */ 22 | #define XMODEM_NAK 0x15 /* Negative Acknowledge */ 23 | #define XMODEM_SYN 0x16 /* Synchronous idle */ 24 | #define XMODEM_CAN 0x18 /* Cancel */ 25 | 26 | void xmodem_receive() { 27 | uint8_t ch; 28 | int len = 0; 29 | uint8_t seq = 0; 30 | uint8_t crc = 0; 31 | uint8_t input_buffer[128]; 32 | int state = WAITING_TO_START; 33 | 34 | while (state != STOP) { 35 | for (int i=0; state == WAITING_TO_START; i++) { 36 | uart_putc(XMODEM_ACK); 37 | sleep(1); 38 | while (uart_readable()) { 39 | uart_getc((char *)&ch); 40 | if (ch == XMODEM_SOH) { 41 | state = WAITING_FOR_SEQ; 42 | } 43 | } 44 | if (i <= 10) { 45 | uart_putc(XMODEM_CAN); 46 | uart_putc(XMODEM_CAN); 47 | uart_puts("Aborting"); 48 | return; 49 | } 50 | } 51 | 52 | while (state == WAITING_FOR_SOH) { 53 | while (!uart_readable()); 54 | uart_getc((char *)&ch); 55 | if (ch == XMODEM_SOH) { 56 | state = WAITING_FOR_SEQ; 57 | } 58 | } 59 | 60 | while (state == WAITING_FOR_SEQ) { 61 | while (!uart_readable()); 62 | uart_getc((char *)&ch); 63 | if (seq+1 == ch) { 64 | seq++; 65 | state = WAITING_FOR_CMPL; 66 | } else if (seq == ch) { 67 | state = DROP_UNTIL_SOH_ACK; 68 | } else { 69 | state = DROP_UNTIL_SOH_NAK; 70 | } 71 | } 72 | 73 | while (state == WAITING_FOR_CMPL) { 74 | for (int i=0; !uart_readable(); i++) { 75 | sleep(1); 76 | if (i == 10) { 77 | uart_putc(XMODEM_CAN); 78 | uart_putc(XMODEM_CAN); 79 | uart_puts("Aborting"); 80 | return; 81 | } 82 | } 83 | uart_getc((char *)&ch); 84 | if (ch == ((255 & seq) ^ 255)) { 85 | state = RECEIVING_DATA; 86 | } else { 87 | state = DROP_UNTIL_SOH_NAK; 88 | } 89 | } 90 | 91 | while (state == DROP_UNTIL_SOH_ACK || state == DROP_UNTIL_SOH_NAK) { 92 | while (!uart_readable()) { 93 | } 94 | len++; 95 | if (len == 129) { 96 | if (state == DROP_UNTIL_SOH_ACK) 97 | uart_putc(XMODEM_ACK); 98 | else if (state == DROP_UNTIL_SOH_NAK) 99 | uart_putc(XMODEM_NAK); 100 | state = WAITING_FOR_SOH; 101 | } 102 | } 103 | 104 | while (state == RECEIVING_DATA) { 105 | while (!uart_readable()) { 106 | } 107 | uart_getc((char *) &ch); 108 | input_buffer[len] = ch; 109 | len++; 110 | if (len == 128) 111 | state = WAITING_FOR_CRC; 112 | } 113 | 114 | while (state == WAITING_FOR_CRC) { 115 | while (!uart_readable()) { 116 | } 117 | uart_getc((char *) &ch); 118 | crc = 0; 119 | for (int i=0; i< len; i++) { 120 | crc += input_buffer[i]; 121 | } 122 | if (crc == ch) { 123 | uart_putc(XMODEM_ACK); 124 | } else { 125 | uart_putc(XMODEM_NAK); 126 | } 127 | state = WAITING_FOR_SOH; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /power.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef POWER_H 3 | #define POWER_H 4 | 5 | #define SBYCR (*(volatile unsigned char*) (0xffff84)) /* Standby control register */ 6 | #define LPWRCR (*(volatile unsigned char*) (0xffff85)) /* Low power control register */ 7 | #define MSTPCRH (*(volatile unsigned char*) (0xffff86)) /* Module stop control register H */ 8 | #define MSTPCRL (*(volatile unsigned char*) (0xffff87)) /* Module stop control register L */ 9 | 10 | /* module stop control register */ 11 | #define MSTPCRH_MSTP15 (1 << 7) /* reserved */ 12 | #define MSTPCRH_MSTP14 (1 << 6) /* Data transfer controller (DTC) */ 13 | #define MSTPCRH_MSTP13 (1 << 5) /* 16-bit free-running timer (FRT) */ 14 | #define MSTPCRH_MSTP12 (1 << 4) /* 8-bit timers (TMR_0, TMR1) */ 15 | #define MSTPCRH_MSTP11 (1 << 3) /* 8-bit PWM timer (PWM), 14-bit PWM timer(PWMX) */ 16 | #define MSTPCRH_MSTP10 (1 << 2) /* D/A converter */ 17 | #define MSTPCRH_MSTP9 (1 << 1) /* A/D converter */ 18 | #define MSTPCRH_MSTP8 (1 << 0) /* 8-bit timers (TMR_X, TMR_Y), timer connection*/ 19 | #define MSTPCRL_MSTP7 (1 << 7) /* Serial communication interface_0 (SCI_0) */ 20 | #define MSTPCRL_MSTP6 (1 << 6) /* Serial communication interface_1 (SCI_1) */ 21 | #define MSTPCRL_MSTP5 (1 << 5) /* Serial communication interface_2 (SCI_2) */ 22 | #define MSTPCRL_MSTP4 (1 << 4) /* I2C bus interface_0 (IIC_0) */ 23 | #define MSTPCRL_MSTP3 (1 << 3) /* I2C bus interface_1 (IIC_1) */ 24 | #define MSTPCRL_MSTP2 (1 << 2) /* Host interface (XBS), 25 | keyboard buffer controller, 26 | keyboard matrix interrupt mask register (KMIMR) 27 | keyboard matrix interrupt mask register A (KMIMRA) 28 | port 6 pull-up MOS control register (KMPCR) */ 29 | #define MSTPCRL_MSTP1 (1 << 1) /* no operations will change */ 30 | #define MSTPCRL_MSTP0 (1 << 0) /* Host interface (LPC) 31 | wake-up even interupt mask register B (WUEMRB) */ 32 | /* module stop control register function names */ 33 | #define MSTPCRH_MSTP15 (1 << 7) /* reserved */ 34 | #define MSTPCRH_DTC (1 << 6) /* Data transfer controller (DTC) */ 35 | #define MSTPCRH_FRT (1 << 5) /* 16-bit free-running timer (FRT) */ 36 | #define MSTPCRH_TMR01 (1 << 4) /* 8-bit timers (TMR_0, TMR1) */ 37 | #define MSTPCRH_PWM (1 << 3) /* 8-bit PWM timer (PWM), 14-bit PWM timer(PWMX) */ 38 | #define MSTPCRH_DAC (1 << 2) /* D/A converter */ 39 | #define MSTPCRH_ADC (1 << 1) /* A/D converter */ 40 | #define MSTPCRH_TMRXY (1 << 0) /* 8-bit timers (TMR_X, TMR_Y), timer connection*/ 41 | #define MSTPCRL_SCI0 (1 << 7) /* Serial communication interface_0 (SCI_0) */ 42 | #define MSTPCRL_SCI1 (1 << 6) /* Serial communication interface_1 (SCI_1) */ 43 | #define MSTPCRL_SCI2 (1 << 5) /* Serial communication interface_2 (SCI_2) */ 44 | #define MSTPCRL_IIC0 (1 << 4) /* I2C bus interface_0 (IIC_0) */ 45 | #define MSTPCRL_IIC1 (1 << 3) /* I2C bus interface_1 (IIC_1) */ 46 | #define MSTPCRL_XBS_KBD (1 << 2) /* Host interface (XBS), 47 | keyboard buffer controller, 48 | keyboard matrix interrupt mask register (KMIMR) 49 | keyboard matrix interrupt mask register A (KMIMRA) 50 | port 6 pull-up MOS control register (KMPCR) */ 51 | #define MSTPCRL_NOP (1 << 1) /* no operations will change */ 52 | #define MSTPCRL_LPC (1 << 0) /* Host interface (LPC) 53 | wake-up even interupt mask register B (WUEMRB) */ 54 | 55 | 56 | #endif /* POWER_H */ 57 | -------------------------------------------------------------------------------- /lpc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LPC_H 3 | #define LPC_H 4 | 5 | #define LPC_HICR0 (*(volatile unsigned char*) (0xffffFF)) /* */ 6 | #define LPC_HICR0_LPC3E (1 << 7) 7 | #define LPC_HICR0_LPC2E (1 << 6) 8 | #define LPC_HICR0_LPC1E (1 << 5) 9 | #define LPC_HICR0_FGA20E (1 << 4) 10 | #define LPC_HICR0_SDWNE (1 << 3) 11 | #define LPC_HICR0_PMEE (1 << 2) 12 | #define LPC_HICR0_LSMIE (1 << 1) 13 | #define LPC_HICR0_LSCIE (1 << 0) 14 | 15 | #define LPC_HICR1 (*(volatile unsigned char*) (0xffffFF)) /* */ 16 | #define LPC_HICR1_LPCBSY (1 << 7) 17 | #define LPC_HICR1_CLKREQ (1 << 6) 18 | #define LPC_HICR1_IRQBSY (1 << 5) 19 | #define LPC_HICR1_LRSTB (1 << 4) 20 | #define LPC_HICR1_SWNB (1 << 3) 21 | #define LPC_HICR1_PMEB (1 << 2) 22 | #define LPC_HICR1_LSMIB (1 << 1) 23 | #define LPC_HICR1_LSCIB (1 << 0) 24 | 25 | #define LPC_TMR0MW (*(volatile unsigned char*) (0xfffe20)) /* Bidirectional data register 0MW */ 26 | #define LPC_TWR0SW (*(volatile unsigned char*) (0xfffe20)) /* Bidirectional data register 0SW */ 27 | #define LPC_TWR1 (*(volatile unsigned char*) (0xfffe21)) /* Bidirectional data register 1 */ 28 | #define LPC_TWR2 (*(volatile unsigned char*) (0xfffe22)) /* Bidirectional data register 2 */ 29 | #define LPC_TWR3 (*(volatile unsigned char*) (0xfffe23)) /* Bidirectional data register 3 */ 30 | #define LPC_TWR4 (*(volatile unsigned char*) (0xfffe24)) /* Bidirectional data register 4 */ 31 | #define LPC_TWR5 (*(volatile unsigned char*) (0xfffe25)) /* Bidirectional data register 5 */ 32 | #define LPC_TWR6 (*(volatile unsigned char*) (0xfffe26)) /* Bidirectional data register 6 */ 33 | #define LPC_TWR7 (*(volatile unsigned char*) (0xfffe27)) /* Bidirectional data register 7 */ 34 | #define LPC_TWR8 (*(volatile unsigned char*) (0xfffe28)) /* Bidirectional data register 8 */ 35 | #define LPC_TWR9 (*(volatile unsigned char*) (0xfffe29)) /* Bidirectional data register 9 */ 36 | #define LPC_TWR10 (*(volatile unsigned char*) (0xfffe2a)) /* Bidirectional data register 10 */ 37 | #define LPC_TWR11 (*(volatile unsigned char*) (0xfffe2b)) /* Bidirectional data register 11 */ 38 | #define LPC_TWR12 (*(volatile unsigned char*) (0xfffe2c)) /* Bidirectional data register 12 */ 39 | #define LPC_TWR13 (*(volatile unsigned char*) (0xfffe2d)) /* Bidirectional data register 13 */ 40 | #define LPC_TWR14 (*(volatile unsigned char*) (0xfffe2e)) /* Bidirectional data register 14 */ 41 | #define LPC_TWR15 (*(volatile unsigned char*) (0xfffe2f)) /* Bidirectional data register 15 */ 42 | 43 | #define LPC_IDR3 (*(volatile unsigned char*) (0xfffe30)) /* Input data register 3 */ 44 | #define LPC_ODR3 (*(volatile unsigned char*) (0xfffe31)) /* Output data register 3 */ 45 | #define LPC_STR3 (*(volatile unsigned char*) (0xfffe32)) /* Status data register 3 */ 46 | #define LPC_LADR3H (*(volatile unsigned char*) (0xfffe34)) /* LPC channel address register H */ 47 | #define LPC_LADR3L (*(volatile unsigned char*) (0xfffe35)) /* LPC channel address register L */ 48 | #define LPC_SIRQCR0 (*(volatile unsigned char*) (0xfffe36)) /* SERIRQ control register 0 */ 49 | #define LPC_SIRQCR1 (*(volatile unsigned char*) (0xfffe37)) /* SERIRQ control register 1 */ 50 | #define LPC_IDR1 (*(volatile unsigned char*) (0xfffe38)) /* Input data register 1 */ 51 | #define LPC_ODR1 (*(volatile unsigned char*) (0xfffe39)) /* Output data register 1 */ 52 | #define LPC_STR1 (*(volatile unsigned char*) (0xfffe3a)) /* Status data register 1 */ 53 | #define LPC_IDR2 (*(volatile unsigned char*) (0xfffe3c)) /* Input data register 2 */ 54 | #define LPC_ODR2 (*(volatile unsigned char*) (0xfffe3d)) /* Output data register 2 */ 55 | #define LPC_STR2 (*(volatile unsigned char*) (0xfffe3e)) /* Status data register 2 */ 56 | #define LPC_HISEL (*(volatile unsigned char*) (0xfffe3e)) /* Host interface select register */ 57 | #define LPC_HICR0 (*(volatile unsigned char*) (0xfffe3e)) /* Host interface control register 0 */ 58 | #define LPC_HICR1 (*(volatile unsigned char*) (0xfffe3e)) /* Host interface control register 1 */ 59 | #define LPC_HICR2 (*(volatile unsigned char*) (0xfffe3e)) /* Host interface control register 2 */ 60 | #define LPC_HICR3 (*(volatile unsigned char*) (0xfffe3e)) /* Host interface control register 3 */ 61 | 62 | void enable_lpc(int channel); 63 | void lpc_set_channel3_address(uint16_t address, uint8_t twr_enable); 64 | 65 | #endif /* LPC_H */ 66 | -------------------------------------------------------------------------------- /serial.c: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "sleep.h" 4 | #include "serial.h" 5 | #include "power.h" 6 | 7 | #include "ringbuffer.h" 8 | #include "led.h" 9 | 10 | #define UART_RXBUFFERSIZE 128 11 | #define UART_TXBUFFERSIZE 128 12 | 13 | struct baudrate { 14 | enum e_baudrate baudrate; 15 | uint8_t n; 16 | uint8_t brr; 17 | }; 18 | 19 | static const struct baudrate baudrate_10mhz[] = { 20 | {.baudrate = B4800, .n = 0, .brr = 64}, /* Error 0.16 % */ 21 | {.baudrate = B9600, .n = 0, .brr = 32}, /* Error -1.36 % */ 22 | {.baudrate = B19200, .n = 0, .brr = 15}, /* Error 1.73 % */ 23 | {.baudrate = B31250, .n = 0, .brr = 9}, /* Error 0.00 % */ 24 | {.baudrate = B38400, .n = 0, .brr = 8}, /* Error 1.73 % */ 25 | }; 26 | 27 | static int set_baudrate(enum e_baudrate baudrate) { 28 | for(short i=0; i < ARRAY_SIZE(baudrate_10mhz); i++) { 29 | if (baudrate_10mhz[i].baudrate != baudrate) 30 | continue; 31 | 32 | SMR_1 &= ~SMR_CKS0 & ~SMR_CKS1; 33 | SMR_1 |= (baudrate_10mhz[i].n & 0x3); 34 | 35 | BRR_1 = baudrate_10mhz[i].brr; 36 | 37 | return 0; 38 | } 39 | return 1; 40 | } 41 | 42 | int setup_serial(enum e_baudrate baudrate, short enable_interupts) { 43 | 44 | /* See H8S/2140B Group Hardware Manual 45 | * Page 380, Rev. 3.00, Mar 21, 2006 REJ09B0300-0300 46 | */ 47 | 48 | /* enable serial interace 1 */ 49 | MSTPCRL &= ~MSTPCRL_SCI1; 50 | 51 | /* clear Tx/Rx enable bits */ 52 | SCR_1 &= ~SCR_TE & ~SCR_RE; 53 | 54 | /* CKE0/1 = 0b00 55 | * set clock mode to internal clock + release SCK pin */ 56 | SCR_1 &= ~SCR_CKE0 & ~SCR_CKE1; 57 | 58 | /* no parity 59 | * 8 data bits 60 | * 1 stop bit 61 | * async communication 62 | * 63 | * speed bits are set by set_baudrate() 64 | */ 65 | SMR_1 = 0; 66 | 67 | /* set to normal operation */ 68 | SCMR_1 = 0; 69 | 70 | if (set_baudrate(baudrate)) { 71 | return 1; 72 | } 73 | 74 | /* wait at least 1 bit interval until setting TE/RE TIE/RIE bits */ 75 | usleep(1000); 76 | 77 | SCR_1 |= SCR_TE | SCR_RE; 78 | 79 | if (enable_interupts) 80 | SCR_1 |= SCR_TIE | SCR_RIE | SCR_TEIE; 81 | 82 | return 0; 83 | } 84 | 85 | void uart_putc(const char c) { 86 | /* wait until transmit register is empty */ 87 | while (!(SSR_1 & SSR_TDRE)) 88 | ; 89 | 90 | TDR_1 = c; 91 | 92 | /* clear register empty bit */ 93 | SSR_1 &= ~SSR_TDRE; 94 | } 95 | 96 | void uart_puts(const char *str) { 97 | int len = strlen(str); 98 | for (short i=0; i> 4)); 209 | uart_putc(getlow(value)); 210 | } 211 | 212 | void uart_put_u16(uint16_t value) { 213 | uart_putc(getlow((value >> 12) & 0xf)); 214 | uart_putc(getlow((value >> 8) & 0xf)); 215 | uart_putc(getlow((value >> 4) & 0xf)); 216 | uart_putc(getlow(value & 0xf)); 217 | } 218 | 219 | void uart_put_u32(uint32_t value) { 220 | uart_put_u16(value >> 16); 221 | uart_put_u16(value & 0xffff); 222 | } 223 | 224 | void uart_put_pointer(void *value) { 225 | uart_put_u32((uint32_t)value); 226 | } 227 | 228 | static void uart_print_ringbuffer(struct ringbuffer_t *ring) { 229 | uart_puts("\r\n=ringbuffer"); 230 | uart_puts("\r\npo "); 231 | uart_put_pointer(ring); 232 | uart_puts("\r\nst "); 233 | uart_put_pointer(ring->start); 234 | uart_puts("\r\nla "); 235 | uart_put_pointer(ring->last); 236 | uart_puts("\r\nrd "); 237 | uart_put_pointer(ring->read); 238 | uart_puts("\r\nwr "); 239 | uart_put_pointer(ring->write); 240 | } 241 | 242 | void uart_print_rx_ringbuffer() { 243 | uart_print_ringbuffer(&rxring); 244 | } 245 | 246 | void uart_print_tx_ringbuffer() { 247 | uart_print_ringbuffer(&txring); 248 | } 249 | 250 | void uart_read_poll() { 251 | int uartread = 10; 252 | while (uartread--) { 253 | if (SSR_1 & SSR_RDRF) { 254 | uart_putc(RDR_1); 255 | SSR_1 &= ~(SSR_ORER | SSR_FER | SSR_PER | SSR_RDRF); 256 | } 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /vectors.s: -------------------------------------------------------------------------------- 1 | ; Vector Table for H8S/2633 2 | ; Johann Gysin 3 | ; 18.06.2002 4 | 5 | .h8300s 6 | .section .vectors 7 | .global _vector_table 8 | 9 | _vector_table: 10 | .long _startp ; 0 Power-On Reset 11 | .long _startm ; 1 Manual Reset 12 | .long _unused_isr ; 2 Reserved 13 | .long _unused_isr ; 3 Reserved 14 | .long _unused_isr ; 4 Reserved 15 | .long _unused_isr ; 5 Trace 16 | .long _unused_isr ; 6 Reserved 17 | .long _unused_isr ; 7 External Interrupt (NMI) 18 | .long _unused_isr ; 8 Trap Instruction A 0 19 | .long _unused_isr ; 9 Trap Instruction A 1 20 | .long _unused_isr ; 10 Trap Instruction A 2 21 | .long _unused_isr ; 11 Trap Instruction A 3 22 | .long _unused_isr ; 12 Trap Instruction A 4 23 | .long _unused_isr ; 13 Trap Instruction A 5 24 | .long _unused_isr ; 14 Trap Instruction A 6 25 | .long _unused_isr ; 15 Trap Instruction A 7 26 | .long _unused_isr ; 16 IRQ0 (External Pin) 27 | .long _unused_isr ; 17 IRQ1 (External Pin) 28 | .long _unused_isr ; 18 IRQ2 (External Pin) 29 | .long _unused_isr ; 19 IRQ3 (External Pin) 30 | .long _unused_isr ; 20 IRQ4 (External Pin) 31 | .long _unused_isr ; 21 IRQ5 (External Pin) 32 | .long _unused_isr ; 22 IRQ6 (External Pin) 33 | .long _unused_isr ; 23 IRQ7 (External Pin) 34 | .long _unused_isr ; 24 SWDTEND Software Activation Interrupt End (DTC) 35 | .long _unused_isr ; 25 WOVI0 Interval Timer (Watchdog Timer 0) 36 | .long _unused_isr ; 26 CMI Refresh Timer 37 | .long _unused_isr ; 27 PC Break 38 | .long _unused_isr ; 28 ADI A/D Conversion End 39 | .long _unused_isr ; 29 WOVI1 Interval Timer (Watchdog Timer 1) 40 | .long _unused_isr ; 30 Reserved 41 | .long _unused_isr ; 31 Reserved 42 | .long _unused_isr ; 32 TGI0A TGR0A Input Capture/Compare Match (TPU Channel 0) 43 | .long _unused_isr ; 33 TGI0B TGR0B Input Capture/Compare Match (TPU Channel 0) 44 | .long _unused_isr ; 34 TGI0C TGR0C Input Capture/Compare Match (TPU Channel 0) 45 | .long _unused_isr ; 35 TGI0D TGR0D Input Capture/Compare Match (TPU Channel 0) 46 | .long _unused_isr ; 36 TCI0V Overflow 0 (TPU Channel 0) 47 | .long _unused_isr ; 37 Reserved 48 | .long _unused_isr ; 38 Reserved 49 | .long _unused_isr ; 39 Reserved 50 | .long _unused_isr ; 40 TGI1A TGR1A Input Capture/Compare Match (TPU Channel 1) 51 | .long _unused_isr ; 41 TGI1B TGR1B Input Capture/Compare Match (TPU Channel 1) 52 | .long _unused_isr ; 42 TCI1V Overflow 1 (TPU Channel 1) 53 | .long _unused_isr ; 43 TCI1U Underflow 1 (TPU Channel 1) 54 | .long _unused_isr ; 44 TGI2A TGR2A Input Capture/Compare Match (TPU Channel 2) 55 | .long _unused_isr ; 45 TGI2B TGR2B Input Capture/Compare Match (TPU Channel 2) 56 | .long _unused_isr ; 46 TCI2V Overflow 2 (TPU Channel 2) 57 | .long _unused_isr ; 47 TCI2U Underflow 2 (TPU Channel 2) 58 | .long _unused_isr ; 48 TGI3A TGR3A Input Capture/Compare Match (TPU Channel 3) 59 | .long _unused_isr ; 49 TGI3B TGR3B Input Capture/Compare Match (TPU Channel 3) 60 | .long _unused_isr ; 50 TGI3C TGR3C Input Capture/Compare Match (TPU Channel 3) 61 | .long _unused_isr ; 51 TGI3D TGR3D Input Capture/Compare Match (TPU Channel 3) 62 | .long _unused_isr ; 52 TCI3V Overflow 3 (TPU Channel 3) 63 | .long _unused_isr ; 53 Reserved 64 | .long _unused_isr ; 54 Reserved 65 | .long _unused_isr ; 55 Reserved 66 | .long _unused_isr ; 56 TGI4A TGR4A Input Capture/Compare Match (TPU Channel 4) 67 | .long _unused_isr ; 57 TGI4B TGR4B Input Capture/Compare Match (TPU Channel 4) 68 | .long _unused_isr ; 58 TCI4V Overflow 4 (TPU Channel 4) 69 | .long _unused_isr ; 59 TCI4U Underflow 4 (TPU Channel 4) 70 | .long _unused_isr ; 60 TGI5A TGR5A Input Capture/Compare Match (TPU Channel 5) 71 | .long _unused_isr ; 61 TGI5B TGR5B Input Capture/Compare Match (TPU Channel 5) 72 | .long _unused_isr ; 62 TCI5V Overflow 5 (TPU Channel 5) 73 | .long _unused_isr ; 63 TCI5U Underflow 5 (TPU Channel 5) 74 | .long _unused_isr ; 64 CMIA0 Compare Match A0 (8-Bit Timer Channel 0) 75 | .long _unused_isr ; 65 CMIB0 Compare Match B0 (8-Bit Timer Channel 0) 76 | .long _unused_isr ; 66 OVI0 Overflow 0 (8-Bit Timer Channel 0) 77 | .long _unused_isr ; 67 Reserved 78 | .long _unused_isr ; 68 CMIA1 Compare Match A1 (8-Bit Timer Channel 1) 79 | .long _unused_isr ; 69 CMIB1 Compare Match B1 (8-Bit Timer Channel 1) 80 | .long _unused_isr ; 70 OVI1 Overflow 1 (8-Bit Timer Channel 1) 81 | .long _unused_isr ; 71 Reserved 82 | .long _unused_isr ; 72 DED0A Channel 0 / Channel 0A Transfer End (DMAC) 83 | .long _unused_isr ; 73 DEND0B Channel 0B Transfer End (DMAC) 84 | .long _unused_isr ; 74 DEND1A Channel 1 / Channel 1A Transfer End (DMAC) 85 | .long _unused_isr ; 75 DEND1B Channel 1B Transfer End (DMAC) 86 | .long _unused_isr ; 76 Reserved 87 | .long _unused_isr ; 77 Reserved 88 | .long _unused_isr ; 78 Reserved 89 | .long _unused_isr ; 79 Reserved 90 | .long _unused_isr ; 80 ERI0 Receive Error 0 (SCI Channel 0) 91 | .long _unused_isr ; 81 RXI0 Reception Completed 0 (SCI Channel 0) 92 | .long _unused_isr ; 82 TXI0 Transmit Data Empty 0 (SCI Channel 0) 93 | .long _unused_isr ; 83 TEI0 Transmission End 0 (SCI Channel 0) 94 | .long _eri1_irq ; 84 ERI1 Receive Error 1 (SCI Channel 1) 95 | .long _rxi1_irq ; 85 RXI1 Reception Completed 1 (SCI Channel 1) 96 | .long _unused_isr ; 86 TXI1 Transmit Data Empty 1 (SCI Channel 1) 97 | .long _unused_isr ; 87 TEI1 Transmission End 1 (SCI Channel 1) 98 | .long _unused_isr ; 88 ERI2 Receive Error 2 (SCI Channel 2) 99 | .long _unused_isr ; 89 RXI2 Reception Completed 2 (SCI Channel 2) 100 | .long _unused_isr ; 90 TXI2 Transmit Data Empty 2 (SCI Channel 2) 101 | .long _unused_isr ; 91 TEI2 Transmission End 2 (SCI Channel 2) 102 | .long _unused_isr ; 92 CMIA0 Compare Match A2 (8-Bit Timer Channel 2) 103 | .long _unused_isr ; 93 CMIB0 Compare Match B2 (8-Bit Timer Channel 2) 104 | .long _unused_isr ; 94 OVI0 Overflow 2 (8-Bit Timer Channel 2) 105 | .long _unused_isr ; 95 Reserved 106 | .long _unused_isr ; 96 CMIA1 Compare Match A3 (8-Bit Timer Channel 3) 107 | .long _unused_isr ; 97 CMIB1 Compare Match B3 (8-Bit Timer Channel 3) 108 | .long _unused_isr ; 98 OVI1 Overflow 3 (8-Bit Timer Channel 3) 109 | .long _unused_isr ; 99 Reserved 110 | .long _unused_isr ;100 IICI0 1 Byte Transmission/Reception Completed (IIC Channel 0) Optional 111 | .long _unused_isr ;101 DDCSW1 Format Switch (IIC Channel 0) Optional 112 | .long _unused_isr ;102 IICI1 1 Byte Transmission/Reception Completed (IIC Channel 1) Optional 113 | .long _unused_isr ;103 Reserved 114 | .long _unused_isr ;104 Reserved 115 | .long _unused_isr ;105 Reserved 116 | .long _unused_isr ;106 Reserved 117 | .long _unused_isr ;107 Reserved 118 | .long _unused_isr ;108 Reserved 119 | .long _unused_isr ;109 Reserved 120 | .long _unused_isr ;110 Reserved 121 | .long _unused_isr ;111 Reserved 122 | .long _unused_isr ;112 Reserved 123 | .long _unused_isr ;113 Reserved 124 | .long _unused_isr ;114 Reserved 125 | .long _unused_isr ;115 Reserved 126 | .long _unused_isr ;116 Reserved 127 | .long _unused_isr ;117 Reserved 128 | .long _unused_isr ;118 Reserved 129 | .long _unused_isr ;119 Reserved 130 | .long _unused_isr ;120 ERI3 Reception Error 3 (SCI Channel 3) 131 | .long _unused_isr ;121 RXI3 Reception Completed 3 (SCI Channel 3) 132 | .long _unused_isr ;122 TXI3 Transmission Data Empty 3 (SCI Channel 3) 133 | .long _unused_isr ;123 TEI3 Transmission End 3 (SCI Channel 3) 134 | .long _unused_isr ;124 ERI4 Reception Error 4 (SCI Channel 4) 135 | .long _unused_isr ;125 RXI4 Reception Completed 4 (SCI Channel 4) 136 | .long _unused_isr ;126 TXI4 Transmission Data Empty 4 (SCI Channel 4) 137 | .long _unused_isr ;127 TEI4 Transmission End 4 (SCI Channel 4) 138 | 139 | .end 140 | --------------------------------------------------------------------------------