Serial reformat, minor bug fixes

This commit is contained in:
Curle 2019-09-11 03:58:20 +01:00
parent 5dadfeb8fd
commit c22bd248e3
2 changed files with 64 additions and 72 deletions

View File

@ -618,6 +618,9 @@ static const char* ExceptionStrings[] = {
/* = Sync Functions = */ /* = Sync Functions = */
/* ============================================================= */ /* ============================================================= */
/* Required functions */
size_t strlen(const char* string);
/* System Initialization */ /* System Initialization */
void PrepareSystem(FILELOADER_PARAMS* FLOP); void PrepareSystem(FILELOADER_PARAMS* FLOP);
@ -639,10 +642,13 @@ uint32_t ReadPort(uint16_t Port, int Length);
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length); uint32_t WritePort(uint16_t Port, uint32_t Data, int Length);
/* Serial functions */ /* Serial functions */
void serial_write(const char chr); void serialWrite(const char chr);
void serial_print(const char* data); void serialPrint(const char* data);
void serial_printf(const char* format, ...); void serialPrintf(const char* format, ...);
void init_serial(); void serialInit();
void inttoa(int input, char* output);
void itoh(int input, char* output);
void zeroString(char* string);
/* ==================== Registers ==================== */ /* ==================== Registers ==================== */
size_t ReadModelSpecificRegister(size_t MSR); size_t ReadModelSpecificRegister(size_t MSR);

View File

@ -14,132 +14,118 @@
#include <kernel.h> #include <kernel.h>
#define SERIAL_DATA_PORT(base) (base) #define SERIAL_DATA(base) (base)
#define SERIAL_FIFO_COMMAND_PORT(base) (base + 2) #define SERIAL_DLAB(base) (base + 1)
#define SERIAL_LINE_COMMAND_PORT(base) (base + 3) #define SERIAL_FIFO(base) (base + 2)
#define SERIAL_MODEM_COMMAND_PORT(base) (base + 4) #define SERIAL_LINE(base) (base + 3)
#define SERIAL_LINE_STATUS_PORT(base) (base + 5) #define SERIAL_MODEM(base) (base + 4)
#define SERIAL_COM1_BASE 0x3F8 #define SERIAL_LINE_STATUS(base) (base + 5)
#define COM1 0x3F8
#define SERIAL_LINE_ENABLE_DLAB 0x80
/** serial_set_baud_rate: /** serialSetBaudrate:
* Sets the speed that data is sent via the serial port. * Sets the speed that data is sent via the serial port.
* The default speed is 115200 bits/s. * The default speed is 115200 bits/s.
* The argument given is the divisor of the number. * The argument given is the divisor of the number.
* Hence, the new speed becomes (115200/divisor) bits/s. * Hence, the new speed becomes (115200/divisor) bits/s.
* *
* @param com The COM port to configure.
* @param divisor The new divisor for the baud rate. * @param divisor The new divisor for the baud rate.
*/ */
void serial_set_baud_rate(uint16_t com, uint16_t divisor) { void serialSetBaudrate() {
WritePort(SERIAL_LINE_COMMAND_PORT(com), WritePort(SERIAL_LINE(COM1), 0x80, 1);
SERIAL_LINE_ENABLE_DLAB, 1);
WritePort(SERIAL_DATA_PORT(com), WritePort(SERIAL_DATA(COM1), 0x03, 1);
(divisor >> 8) & 0x00FF, 1);
WritePort(SERIAL_DATA_PORT(com), WritePort(SERIAL_DLAB(COM1), 0x00, 1);
divisor & 0x00FF, 1);
} }
/** serial_configure_line: /** serialConfigure:
* Sets a specific data byteset in the Serial hardware. * Sets a specific data byteset in the Serial hardware.
* Required for expected operation. * Required for expected operation.
*
* @param com The COM port to configure.
*/ */
void serial_configure_line(uint16_t com) { void serialConfigure() {
/* Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 | /* Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 |
* Content: | d | b | parity | s | dl | * Content: | d | b | parity | s | dl |
* Value: | 0 | 0 | 0 0 0 | 0 | 1 1 | = 0x03 * Value: | 0 | 0 | 0 0 0 | 0 | 1 1 | = 0x03
*/ */
WritePort(SERIAL_LINE(COM1), 0x03, 1);
WritePort(SERIAL_LINE_COMMAND_PORT(com), 0x0B, 1);
} }
/** serial_configure_buffers: /** serialConfigureBuffers:
* Enables FIFO (First In First Out) on the Serial line. * Enables FIFO (First In First Out) on the Serial line.
* It clears both the receive and transmit queues. * It clears both the receive and transmit queues.
* It uses a 14 byte wide queue. * It uses a 14 byte wide queue.
* *
* @param com The COM port to configure.
*/ */
void serial_configure_buffers(uint16_t com) { void serialConfigureBuffers() {
/* Bit: | 7 6 | 5 | 4 | 3 | 2 | 1 | 0 | /* Bit: | 7 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* Content: | 1v1 | bs | r | dma | clt | clr | e | * Content: | 1v1 | bs | r | dma | clt | clr | e |
* Value: | 1 1 | 0 | 0 | 0 | 1 | 1 | 1 | = 0xC7 * Value: | 1 1 | 0 | 0 | 0 | 1 | 1 | 1 | = 0xC7
*/ */
WritePort(SERIAL_FIFO_COMMAND_PORT(com), 0xC7, 1); WritePort(SERIAL_FIFO(COM1), 0xC7, 1);
} }
/** serial_configure_modem /** serialConfigureModem:
* @param com The COM port to configure.
*/ */
void serial_configure_modem(uint16_t com) { void serialConfigureModem() {
/* Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | /* Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* Content: | r | r | af | lb | ao2 | ao1 | rts | dtr | * Content: | r | r | af | lb | ao2 | ao1 | rts | dtr |
* Value: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | = 0x03 * Value: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | = 0x03
*/ */
WritePort(SERIAL_MODEM_COMMAND_PORT(com), 0x3, 1); WritePort(SERIAL_MODEM(COM1), 0x03, 1);
} }
/** serial_check_tqueue: /** serialCheck:
* Checks whether the Transmit FIFO Queue is empty on the given port. * Checks whether the Transmit FIFO Queue is empty on the given port.
* *
* @param com The COM port to check.
* @return 0 If the queue is not empty. * @return 0 If the queue is not empty.
* 1 If the queue is empty. * 1 If the queue is empty.
*/ */
int serial_check_tqueue(uint16_t com) { int serialCheck() {
return ReadPort(SERIAL_LINE_STATUS_PORT(com), 1) & 0x20; return ReadPort(SERIAL_LINE_STATUS(COM1), 1) & 0x20;
} }
/** serial_write: /** serial_write:
* Prints a single character to the serial port. * Prints a single character to the serial port.
* Does nothing fancy. * Does nothing fancy.
* @param com The COM port to write to.
* @param data The character to write. * @param data The character to write.
*/ */
void serial_write(const char chr) { void serialWrite(const char chr) {
uint16_t com = SERIAL_COM1_BASE;
//Hang until we have access to the COM port. //Hang until we have access to the COM port.
while(serial_check_tqueue(com) == 0); while(!serialCheck());
WritePort(com, chr, 1); WritePort(COM1, chr, 1);
} }
/** serial_print: /** serialPrint:
* Prints a string to the serial port. * Prints a string to the serial port.
* Does not support ANSI codes, or color. * Does not support ANSI codes, or color.
* *
* @param com The COM port to write to.
* @param data The string to write. * @param data The string to write.
*/ */
void serial_print(const char* data) { void serialPrint(const char* data) {
for(size_t i = 0; i < strlen(data); i++) { for(size_t i = 0; i < strlen(data); i++) {
serial_write(data[i]); serialWrite(data[i]);
} }
} }
/** serial_printf: /** serialPrintf:
* A printf-style function for the serial port. * A printf-style function for the serial port.
* *
* @param format The base string - used to substitute the succeding values. * @param format The base string - used to substitute the succeding values.
* @param ... The substitutions. * @param ... The substitutions.
*/ */
void serial_printf(const char* format, ...) { void serialPrintf(const char* format, ...) {
uint16_t com = SERIAL_COM1_BASE;
uint32_t storage; //To hold temporary variables uint32_t storage; //To hold temporary variables
char stringstore[10] = {0}; //To convert ints to strings. char stringstore[10] = {0}; //To convert ints to strings.
va_list list; va_list list;
@ -152,46 +138,46 @@ void serial_printf(const char* format, ...) {
if(format[i+1] == 'd') { if(format[i+1] == 'd') {
storage = va_arg(list, int); storage = va_arg(list, int);
int_to_ascii(storage, stringstore); inttoa(storage, stringstore);
serial_print(stringstore); serialPrint(stringstore);
empty_string(stringstore); zeroString(stringstore);
i += 2; i += 2;
} else if(format[i+1] == 'x') { } else if(format[i+1] == 'x') {
storage = va_arg(list, int); storage = va_arg(list, int);
int_to_hex(storage, stringstore); itoh(storage, stringstore);
serial_print(stringstore); serialPrint(stringstore);
empty_string(stringstore); zeroString(stringstore);
i += 2; i += 2;
} else if(format[i+1] == 's') { } else if(format[i+1] == 's') {
serial_print(va_arg(list, char*)); serialPrint(va_arg(list, char*));
i += 2; i += 2;
} else { } else {
serial_print("ERROR: Attempting to parse unknown format string."); serialPrint("ERROR: Attempting to parse unknown format string.");
return; return;
} }
} else { } else {
serial_write(format[i]); serialWrite(format[i]);
i++; i++;
} }
} }
va_end(list); //Free the list va_end(list); //Free the list
} }
void init_serial() { void serialInit() {
// Disable interrupts // Disable interrupts
WritePort(SERIAL_COM1_BASE + 1, 0x00, 1); WritePort(SERIAL_DLAB(COM1), 0x00, 1);
// Set baud rate divisor. // Set baud rate divisor to 3
serial_set_baud_rate(SERIAL_COM1_BASE, 3); serialSetBaudrate();
// 8 bits, no parity, one stop bit. // 8 bits, no parity, one stop bit.
serial_configure_line(SERIAL_COM1_BASE); serialConfigure();
// Enable FIFO and clear buffers. // Enable FIFO and clear buffers.
serial_configure_buffers(SERIAL_COM1_BASE); serialConfigureBuffers();
// Enable IRQs, RTS/DSR set. // Enable IRQs, RTS/DSR set.
serial_configure_modem(SERIAL_COM1_BASE); serialConfigureModem();
} }