Add serial driver and irq support
This commit is contained in:
@@ -339,12 +339,16 @@ token = 0xFF - response timeout
|
||||
*******************************************************************************/
|
||||
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
|
||||
{
|
||||
|
||||
(void)addr;
|
||||
(void)buf;
|
||||
(void)token;
|
||||
|
||||
/*
|
||||
uint16_t readAttempts;
|
||||
uint8_t res1, read;
|
||||
uint16_t i;
|
||||
|
||||
/*
|
||||
|
||||
// set token to none
|
||||
*token = 0xFF;
|
||||
|
||||
@@ -391,9 +395,11 @@ uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
|
||||
spi_deselect(0);
|
||||
spi_exchange(0xFF);
|
||||
|
||||
return res1;
|
||||
|
||||
*/
|
||||
|
||||
return res1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
17
sw/kernel/devices/serial.h
Normal file
17
sw/kernel/devices/serial.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _SERIAL_H
|
||||
#define _SERIAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void serial_handle_irq();
|
||||
|
||||
void serial_init();
|
||||
|
||||
void serial_putc(char c);
|
||||
void serial_puts(char* s);
|
||||
|
||||
|
||||
char serial_getc();
|
||||
char serial_getc_nb();
|
||||
|
||||
#endif
|
||||
94
sw/kernel/devices/serial.s
Normal file
94
sw/kernel/devices/serial.s
Normal file
@@ -0,0 +1,94 @@
|
||||
.MACPACK generic
|
||||
|
||||
.autoimport
|
||||
|
||||
.import _enable_irq, _send_eoi, _uart_txb_block
|
||||
|
||||
.importzp tmp1, ptr1
|
||||
|
||||
.export _serial_init
|
||||
.export _serial_handle_irq
|
||||
|
||||
.export _serial_putc, _serial_puts, _serial_getc, _serial_get_nb
|
||||
|
||||
.zeropage
|
||||
|
||||
last_char: .res 1
|
||||
|
||||
|
||||
.code
|
||||
|
||||
UART = $efe6
|
||||
UART_TXB = UART
|
||||
UART_RXB = UART
|
||||
UART_STATUS = UART + 1
|
||||
|
||||
; Initialize Serial Port
|
||||
; No initialization needed, just register irq handler.
|
||||
.proc _serial_init
|
||||
lda #<_serial_handle_irq
|
||||
ldx #>_serial_handle_irq
|
||||
jsr pushax
|
||||
lda #$01
|
||||
jsr _register_irq
|
||||
stz last_char
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; Serial Port IRQ Handler
|
||||
; Get the character and store it.
|
||||
.proc _serial_handle_irq
|
||||
lda UART_RXB
|
||||
sta last_char
|
||||
ora #$80 ; set msb
|
||||
jsr _send_eoi
|
||||
rti
|
||||
.endproc
|
||||
|
||||
; Serial Port Get Character
|
||||
; If a character has not been received, block until one is.
|
||||
.proc _serial_getc
|
||||
L1: lda last_char
|
||||
bpl L1
|
||||
and #$7f
|
||||
sta last_char
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; Serial Port Get Character Non-Blocking
|
||||
; return last character, even if it has already been read.
|
||||
; If the character is new, we still clear the new flag.
|
||||
.proc _serial_get_nb
|
||||
lda last_char
|
||||
bpl L1
|
||||
and #$7f
|
||||
sta last_char
|
||||
L1: rts
|
||||
.endproc
|
||||
|
||||
|
||||
; Serial Port Put Character
|
||||
; send a single character over the serial port.
|
||||
.proc _serial_putc
|
||||
jsr _uart_txb_block
|
||||
cmp #$0a
|
||||
bne @1
|
||||
lda #$0d
|
||||
jsr _uart_txb_block
|
||||
@1: rts
|
||||
.endproc
|
||||
|
||||
; Send a string over the serial port. Needs stlen
|
||||
.proc _serial_puts
|
||||
sta ptr1 ; Store pointer in ptr1
|
||||
stx ptr1+1
|
||||
ldy #$00 ; initialize y to 0
|
||||
L1: lda (ptr1),y ; load character from string
|
||||
beq L2 ; Quit if NULL
|
||||
jsr _uart_txb_block ; send character (does not change y or ptr1)
|
||||
iny ; increment y
|
||||
bne L1 ; If Y == 0, increment high byte of pointer
|
||||
inc ptr1+1
|
||||
bne L1 ; if high byte wraps around, give up
|
||||
L2: rts
|
||||
.endproc
|
||||
@@ -48,7 +48,7 @@ rti
|
||||
sta IRQ_CMD_ADDR
|
||||
lda IRQ_DAT_ADDR
|
||||
; shift by 2 (oh so only 128 interrupts are supported lol)
|
||||
lsr
|
||||
asl
|
||||
tax
|
||||
jmp (irq_table,x)
|
||||
; use that to index jump table
|
||||
@@ -56,6 +56,7 @@ rti
|
||||
|
||||
; void register_irq(void* addr, uint8_t irqn);
|
||||
.proc _register_irq
|
||||
asl
|
||||
tax
|
||||
jsr popa
|
||||
sta irq_table,x
|
||||
@@ -65,6 +66,7 @@ rti
|
||||
lda #$00
|
||||
jsr pusha
|
||||
txa
|
||||
lsr
|
||||
jsr _enable_irq
|
||||
rts
|
||||
.endproc
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "interrupts/interrupt.h"
|
||||
#include "devices/mapper.h"
|
||||
#include "devices/rtc.h"
|
||||
#include "devices/serial.h"
|
||||
|
||||
|
||||
void handle_rtc_interrupt() {
|
||||
@@ -14,6 +15,8 @@ void handle_rtc_interrupt() {
|
||||
|
||||
int main() {
|
||||
|
||||
uint8_t c;
|
||||
|
||||
cputs("Kernel\n");
|
||||
|
||||
cputs("Init Mapper\n");
|
||||
@@ -32,9 +35,15 @@ int main() {
|
||||
|
||||
asm volatile("cli");
|
||||
|
||||
// cputs("Initialize Serial\n");
|
||||
// // init_serial();
|
||||
// enable_irq(2, IRQ_EDGE);
|
||||
cputs("Initialize Serial\n");
|
||||
serial_init();
|
||||
|
||||
serial_puts("Hello from serial!\n");
|
||||
|
||||
c = serial_getc();
|
||||
|
||||
serial_puts("Got a character!: ");
|
||||
serial_putc(c);
|
||||
|
||||
while(1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user