Serial.hpp

/*
 * Serial.h
 *
 *  Created on: Dec 4, 2010
 *      Author: dejagerd
 */

#ifndef SERIAL_H_
#define SERIAL_H_

#include <LPC17xx.h>
#include <stdio.h>
#include <errno.h>
#include "newlibMinimal.h"

/* dtab for an example stream device called "com1" */
//const devoptab_t devoptab_tty0 = {
//		"tty0",
//		NULL,//com1_open_r,
//		NULL,//com1_close_r,
//		NULL,//com1_write_r,
//		NULL//com1_read_r
//};
///Enumeration listing port configurations.
typedef enum {
	///Primary configuration of uart0
	///Transmitting on p0.2
	///Receiving on p0.3
	UART0 = 0,
	///Primary configuration of uart1
	///Transmitting on p0.15
	///Receiving on p0.16
	UART1 = 1,
	///Primary configuration of uart2
	///Transmitting on p0.10
	///Receiving on p0.11
	UART2 = 2,
	///Primary configuration of uart3
	///Transmitting on p0.0
	///Receiving on p0.1
	UART3 = 3,
	///Secondary configuration of uart1
	///Transmitting on p2.0
	///Receiving on p2.1
	UART1_ALT1 = 5,
	///Secondary configuration of uart2
	///Transmitting on p2.8
	///Receiving on p2.9
	UART2_ALT1 = 6,
	///Secondary configuration of uart3
	///Transmitting on p0.25
	///Receiving on p0.26
	UART3_ALT1 = 7,
	///Tertiary configuration of uart3
	///Transmitting on p4.28
	///Receiving on p4.29
	UART3_ALT2 = 11
} UART_PortConfig;

/**
 * Changes the configuration of the current port.
 * @param config Chooses the configuration for this port
 * @param baudrate Baudrate to use on this port
 * @return True if successful, FALSE if failed
 */
int SerialInit(UART_PortConfig config, uint32_t baudrate) {
	uint32_t Fdiv;
	uint32_t pclkdiv, pclk;
	uint32_t UART;
	switch (config % 4) {
	case 0:
		UART = (uint32_t) LPC_UART0;
		break;
	case 1:
		UART = (uint32_t) LPC_UART1;
		break;
	case 2:
		UART = (uint32_t) LPC_UART2;
		break;
	case 3:
		UART = (uint32_t) LPC_UART3;
		break;
	default:
		return 0;
	}

	pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
	switch (pclkdiv) {
	case 0x00:
	default:
		pclk = SystemCoreClock / 4;
		break;
	case 0x01:
		pclk = SystemCoreClock;
		break;
	case 0x02:
		pclk = SystemCoreClock / 2;
		break;
	case 0x03:
		pclk = SystemCoreClock / 8;
	}
	Fdiv = (pclk / 16) / baudrate; /*baud rate */
	switch (config) {
	case 0:
		LPC_PINCON->PINSEL0 &= ~((3 << 4) | (3 << 6));
		LPC_PINCON->PINSEL0 |= ((1 << 4) | (1 << 6)); /* RxD0 is P0.3 and TxD0 is P0.2 */
		NVIC_EnableIRQ(UART0_IRQn);
		break;
	case 1:
		LPC_PINCON->PINSEL0 &= ~((3 << 30));
		LPC_PINCON->PINSEL0 |= ((1 << 30));
		LPC_PINCON->PINSEL1 &= ~((3 << 0));
		LPC_PINCON->PINSEL1 |= ((1 << 0)); /* Enable RxD1 P2.1, TxD1 P2.0 */
		NVIC_EnableIRQ(UART1_IRQn);
		break;
	case 2:
		LPC_PINCON->PINSEL0 &= ~((3 << 20) | (3 << 22));
		LPC_PINCON->PINSEL0 |= ((1 << 20) | (1 << 22)); /* Enable RxD1 P2.1, TxD1 P2.0 */
		NVIC_EnableIRQ(UART2_IRQn);
		break;
	case 3:
		LPC_PINCON->PINSEL0 &= ~((3 << 0) | (3 << 2));
		LPC_PINCON->PINSEL0 |= ((2 << 0) | (2 << 2)); /* RxD3 is P0.1 and TxD0 is P0.1 */
		NVIC_EnableIRQ(UART3_IRQn);
		break;
	case 5:
		LPC_PINCON->PINSEL4 &= ~((3 << 4) | (3 << 6));
		LPC_PINCON->PINSEL4 |= ((2 << 4) | (2 << 6)); /* RxD0 is P0.3 and TxD0 is P0.2 */
		NVIC_EnableIRQ(UART1_IRQn);
		break;
	case 6:
		LPC_PINCON->PINSEL4 &= ~((3 << 16) | (3 << 18));
		LPC_PINCON->PINSEL4 |= ((2 << 16) | (2 << 18)); /* RxD0 is P0.3 and TxD0 is P0.2 */
		NVIC_EnableIRQ(UART2_IRQn);
		break;
	case 7:
		LPC_PINCON->PINSEL1 &= ~((3 << 18) | (3 << 20));
		LPC_PINCON->PINSEL1 |= ((3 << 18) | (3 << 20)); /* RxD0 is P0.3 and TxD0 is P0.2 */
		NVIC_EnableIRQ(UART3_IRQn);
		break;
	case 11:
		LPC_PINCON->PINSEL9 &= ~((3 << 24) | (3 << 26));
		LPC_PINCON->PINSEL9 |= ((3 << 24) | (3 << 26)); /* RxD0 is P0.3 and TxD0 is P0.2 */
		NVIC_EnableIRQ(UART3_IRQn);
		break;

	default:
		return (0);
	}
	switch (config % 4) {
	case 0:
		((LPC_UART0_TypeDef*) UART)->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
		((LPC_UART0_TypeDef*) UART)->DLM = Fdiv / 256;
		((LPC_UART0_TypeDef*) UART)->DLL = Fdiv % 256;
		((LPC_UART0_TypeDef*) UART)->LCR = 0x03; /* DLAB = 0 */
		((LPC_UART0_TypeDef*) UART)->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
	case 1:
		((LPC_UART1_TypeDef*) UART)->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
		((LPC_UART1_TypeDef*) UART)->DLM = Fdiv / 256;
		((LPC_UART1_TypeDef*) UART)->DLL = Fdiv % 256;
		((LPC_UART1_TypeDef*) UART)->LCR = 0x03; /* DLAB = 0 */
		((LPC_UART1_TypeDef*) UART)->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
	case 2:
	case 3:
		((LPC_UART_TypeDef*) UART)->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
		((LPC_UART_TypeDef*) UART)->DLM = Fdiv / 256;
		((LPC_UART_TypeDef*) UART)->DLL = Fdiv % 256;
		((LPC_UART_TypeDef*) UART)->LCR = 0x03; /* DLAB = 0 */
		((LPC_UART_TypeDef*) UART)->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
	}
	//	uart_buf = bufmake(80);
	/*
	 switch(config%4){
	 case 0:
	 ((LPC_UART0_TypeDef*)UART)->IER = IER_RBR | IER_THRE | IER_RLS;
	 case 1:
	 ((LPC_UART1_TypeDef*)UART)->IER = IER_RBR | IER_THRE | IER_RLS;
	 case 2:
	 case 3:
	 ((LPC_UART_TypeDef*)UART)->IER = IER_RBR | IER_THRE | IER_RLS;
	 }*/

	return (-1);
}

int uart_putchar(char c, FILE *stream) {

	if (c == '\n')
		uart_putchar('\r', stream);
	LPC_UART0->THR = c;
	while (!(LPC_UART0->LSR & (1 << 6)))
		;//TSR && THR are not empty
	return 0;
}
int putst(char* s) {
	while (*s) {
		uart_putchar(*s, NULL);
		s++;

	}
	return 0;
}

#endif /* SERIAL_H_ */


1 comment

15 Apr 2011 . Edited: 15 Apr 2011
Hi, got a problem with your code: everytime i use putst(), it prints the string 2 times in the terminal. any idea what happens there? another issue is in newlibminimal.h: __attribute__((weak)) const devoptab_t devoptab_tty0 = { "tty0", _undef_open_r, _undef_close_r, _undef_write_r, _undef_read_r }; cannot compile in eclipse, error says that "must be public". after commenting __attribute__((weak)) it works fine

You need to log in to post a comment