Hello all,
I have posted here a few times about my problems with the logomatic. Anyways, I am trying to obviously log data, but first I want to logomatic to respond to specific characters sent over serial. I want it to receive some characters, let’s say $$ for example, and then respond with, let’s say #1 for example. All it does is echo back what is sent. Here is the main.c code. Pay attention to the initialize function with rprintf_devopen. I think that this is where I need to focus. I did find another thread where a guy was trying to transmit. He said that he figured it out, but his suggestion did not work for me.
/*********************************************************************************
* Logomatic V2 Firmware
* Sparkfun Electronics 2008
* ******************************************************************************/
//Notice the comments in the UART0ISR_2 and mode_action functions
/*******************************************************
* Header Files
******************************************************/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "LPC21xx.h"
//UART0 Debugging
#include "serial.h"
#include "rprintf.h"
//Needed for main function calls
#include "main_msc.h"
#include "fat.h"
#include "armVIC.h"
#include "itoa.h"
#include "rootdir.h"
#include "sd_raw.h"
/*******************************************************
* Global Variables
******************************************************/
#define ON 1
#define OFF 0
char RX_array1[512];
char RX_array2[512];
char TX_array1[3] = "DL1";
char query1 [3] = "ID?";
char query2 [7] = "protov?";
char stop [2] = "$"; //I created this array in case we wanted something to stop logging, the '$' characters are completely
//arbitrary and only put there to ensure that the stop mechanism works
int trig = 13;
char log_array1 = 0;
char log_array2 = 0;
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
short RX_in = 0;
int flag1 = 0;
int flag2 = 0;
int flagstop = 0;
unsigned char flag = 0;
signed int stringSize;
struct fat_file_struct* handle;
struct fat_file_struct * fd;
char stringBuf[256];
// Default Settings
static char mode = 1;
static char asc = 'Y';
static int baud = 9600;
/*******************************************************
* Function Declarations
******************************************************/
//void power_down(void);
void set_time(void);
void Initialize(void);
void setup_uart0(int newbaud, char want_ints);
void mode_0(void);
void mode_1(void);
void mode_2(void);
void mode_action(void);
void Log_init(void);
void test(void);
void stat(int statnum, int onoff);
void AD_conversion(int regbank);
void feed(void);
static void IRQ_Routine(void) __attribute__ ((interrupt("IRQ")));
static void UART0ISR(void); //__attribute__ ((interrupt("IRQ")));
static void UART0ISR_2(void); //__attribute__ ((interrupt("IRQ")));
void rtc_int(void) __attribute__ ((interrupt("IRQ")));
void FIQ_Routine(void) __attribute__ ((interrupt("FIQ")));
void SWI_Routine(void) __attribute__ ((interrupt("SWI")));
void UNDEF_Routine(void) __attribute__ ((interrupt("UNDEF")));
void fat_initialize(void);
void delay_ms(int count);
/*******************************************************
* MAIN
******************************************************/
int main (void)
{
int i;
//power_down();
set_time ();
enableFIQ();
Initialize();
setup_uart0(9600, 0);
fat_initialize();
// Flash Status Lights
for(i = 0; i < 5; i++)
{
stat(0,ON);
delay_ms(50);
stat(0,OFF);
stat(1,ON);
delay_ms(50);
stat(1,OFF);
}
Log_init();
sd_raw_sync();
if(mode == 0){ mode_0(); }
else if(mode == 1){ mode_1(); }
return 0;
}
/*******************************************************
* Initialize
******************************************************/
#define PLOCK 0x400
/*Function for setting the date and time*/
void set_time(void)
{
PCONP |= (1<<9); //Ensure RTC is powered
CCR = 0x13; //Turn off RTC
YEAR = 2015;
MONTH = 07;
DOM = 27; //Day of Month
HOUR = 23;
MIN = 59;
SEC = 0;
CCR = 0x11; //Turn RTC back on
}
void Initialize(void)
{
rprintf_devopen(putc_serial0);//This function can be found in rprintf.c in 'GitHub\Logomatic\Firmware\lib'. I cannot understand it, but it
//is important and may hold the key to transmitting characters.
PINSEL0 = 0xCF351505;
PINSEL1 = 0x15441801;
IODIR0 |= 0x00000884;
IOSET0 = 0x00000080;
S0SPCR = 0x08; // SPI clk to be pclk/8
S0SPCR = 0x30; // master, msb, first clk edge, active high, no ints
}
void feed(void)
{
PLLFEED=0xAA;
PLLFEED=0x55;
}
static void UART0ISR(void)
{
char temp;
if(RX_in < 512)
{
RX_array1[RX_in] = U0RBR;
RX_in++;
if(RX_in == 512) log_array1 = 1;
}
else if(RX_in >= 512)
{
RX_array2[RX_in-512] = U0RBR;
RX_in++;
if(RX_in == 1024)
{
log_array2 = 1;
RX_in = 0;
}
}
temp = U0IIR; // Have to read this to clear the interrupt
VICVectAddr = 0;
}
/*This function was changed a lot from the original Github version
This function describes a mode that requires a trigger character to log data.
Data will be stored in a temporary register until the trigger is seen, at
that point, the data will be logged to the sd-card*/
static void UART0ISR_2(void)
{
char temp;
trig = 13; //This is where you set the trigger character in decimal, in this case a carriage return.
temp = U0RBR; //U0RBR is the receive buffer on the chip, refer to datasheet.
if(temp == query1[counter1]) //This segment looks for the characters "ID?" from the U0RBR
{ //query1 is defined at the top of the program
counter1++;
if(counter1 >= 3)
{
flag1 = 1; //This keeps track of whether or not query1 was found
counter1 = 0;
stat(1,ON);
delay_ms(50);
stat(1,OFF);
RX_in = 0;
temp = 0;
putc_serial1(49); //This function is in the following path within the Github folder 'GitHub\Logomatic\Firmware\lib'.
} //It is in the 'serial C file'. I am attempting to transmit a specific character upon receiving
//query1. It is not yet working, but you can notice the 'stat' section refers to the onboard leds
//so, the led turns on upon receiving query1, but no transmission. This needs to be worked on
}
if(temp == query2[counter2] && flag1 == 1) //This segment looks for "protov?" from the U0RBR, but only after query1 has been found
{
counter2++;
if(counter2 >= 7)
{
flag2 = 1; //This keeps track of whether or not query2 was found
counter2 = 0;
stat(1,ON);
delay_ms(50);
stat(1,OFF);
RX_in = 0;
temp = 0;
putc_serial1(49);//This function is in the following path within the Github folder 'GitHub\Logomatic\Firmware\lib'.
} //It is in the 'serial C file'. I am attempting to transmit a specific character upon receiving
//query2. It is not yet working, but you can notice the 'stat' section refers to the onboard leds
//so, the led turns on upon receiving query2, but no transmission. This needs to be worked on
}
if(temp == stop[counter3]) //This if segment looks for certain characters in the receive buffer to stop logging
{
counter3++;
if(counter3 >= 2)
{
flagstop = 1; //This flagstop keeps track of whether or not stop was found. When the stop characters are found,
flag1 = 0; //the query1 and query2 flags will be reset. So, in order to log again these queries must be sent again
flag2 = 0; //this may seem obvious, but deserves mention.
counter3 = 0;
stat(1,ON);
delay_ms(500);
stat(1,OFF);
RX_in = 0;
temp = 0;
}
flagstop = 0; //Reset the stop flag in order to wait once again for the query 1&2
}
if(RX_in == 0)
{
memset (RX_array1, 0, 512); // This clears the RX_array to make way for new data
memset (RX_array2, 0, 512);
}
if(RX_in < 512 && flag1 == 1 && flag2 == 1) //We cannot log data until we see both flags 1&2 and after we see these flags,
{ //we must then see the trigger character "carriage return
RX_array1[RX_in] = temp;
RX_in++;
if(temp == trig)
{
RX_array1[RX_in] = 10; // delimiters
log_array1 = 1;
RX_in = 0;
}
}
else if(RX_in >= 512 && flag1 == 1 && flag2 == 1) //This else if is here in case the RX_in is greater than 512 because the RX_arrays are defined to
{ //be of size 512. If this happens we don't want to lose data, so we must put the overflow into another register.
RX_array2[RX_in - 512] = temp;
RX_in++;
RX_array1[512] = 10; // delimiters
RX_array1[512 + 1] = 13;
log_array1 = 1;
if(RX_in == 1024 || temp == trig)
{
RX_array2[RX_in - 512] = 10; // delimiters
log_array2 = 1;
RX_in = 0;
}
}
temp = U0IIR; // have to read this to clear the interrupt
VICVectAddr = 0;
}
void FIQ_Routine(void)
{
char a;
int j;
stat(0,ON);
for(j = 0; j < 5000000; j++);
stat(0,OFF);
a = U0RBR;
a = U0IIR; // have to read this to clear the interrupt
}
void SWI_Routine(void)
{
while(1);
}
void UNDEF_Routine(void)
{
stat(0,ON);
}
void setup_uart0(int newbaud, char want_ints)
{
baud = newbaud;
U0LCR = 0x83; // 8 bits, no parity, 1 stop bit, DLAB = 1
if(baud == 1200)
{
U0DLM = 0x0C;
U0DLL = 0x00;
}
else if(baud == 2400)
{
U0DLM = 0x06;
U0DLL = 0x00;
}
else if(baud == 4800)
{
U0DLM = 0x03;
U0DLL = 0x00;
}
else if(baud == 9600)
{
U0DLM = 0x01;
U0DLL = 0x80;
}
else if(baud == 19200)
{
U0DLM = 0x00;
U0DLL = 0xC0;
}
else if(baud == 38400)
{
U0DLM = 0x00;
U0DLL = 0x60;
}
else if(baud == 57600)
{
U0DLM = 0x00;
U0DLL = 0x40;
}
else if(baud == 115200)
{
U0DLM = 0x00;
U0DLL = 0x20;
}
U0FCR = 0x01;
U0LCR = 0x03; //DLAB = 0
if(want_ints == 1)
{
enableIRQ();
VICIntSelect &= ~0x00000040;
VICIntEnable |= 0x00000040;
VICVectCntl1 = 0x26;
VICVectAddr1 = (unsigned int)UART0ISR;
U0IER = 0x03;
}
else if(want_ints == 2)
{
enableIRQ();
VICIntSelect &= ~0x00000040;
VICIntEnable |= 0x00000040;
VICVectCntl2 = 0x26;
VICVectAddr2 = (unsigned int)UART0ISR_2;
U0IER = 0X03;
}
else if(want_ints == 0)
{
VICIntEnClr = 0x00000040;
U0IER = 0x00;
}
}
void stat(int statnum, int onoff)
{
if(statnum) // Stat 1
{
if(onoff){ IOCLR0 = 0x00000800; } // On
else { IOSET0 = 0x00000800; } // Off
}
else // Stat 0
{
if(onoff){ IOCLR0 = 0x00000004; } // On
else { IOSET0 = 0x00000004; } // Off
}
}
void Log_init(void)
{
int x, mark = 0, ind = 0;
char temp;
// signed char handle;
if(root_file_exists("LOGCON.txt"))
{
//rprintf("\n\rFound LOGcon.txt\n");
fd = root_open("LOGCON.txt");
stringSize = fat_read_file(fd, (unsigned char *)stringBuf, 512);
stringBuf[stringSize] = '\0';
fat_close_file(fd);
}
else
{
//rprintf("Couldn't find LOGcon.txt, creating...\n");
fd = root_open_new("LOGCON.txt");
if(fd == NULL)
{
rprintf("Error creating LOGCON.txt, locking up...\n\r");
while(1)
{
stat(0,ON);
delay_ms(50);
stat(0,OFF);
stat(1,ON);
delay_ms(50);
stat(1,OFF);
}
}
strcpy(stringBuf, "MODE = 1\r\nASCII = Y\r\nBaud = 4\r\n");
stringSize = strlen(stringBuf);
fat_write_file(fd, (unsigned char*)stringBuf, stringSize);
sd_raw_sync();
}
for(x = 0; x < stringSize; x++)
{
temp = stringBuf[x];
if(temp == 10)
{
mark = x;
ind++;
if(ind == 1)
{
mode = stringBuf[mark-2]-48; // 0 = auto uart, 1 = trigger uart
rprintf("mode = %d\n\r",mode);
}
else if(ind == 2)
{
asc = stringBuf[mark-2]; // default is 'N'
rprintf("asc = %c\n\r",asc);
}
else if(ind == 3)
{
if(stringBuf[mark-2] == '1'){ baud = 1200; }
else if(stringBuf[mark-2] == '2'){ baud = 2400; }
else if(stringBuf[mark-2] == '3'){ baud = 4800; }
else if(stringBuf[mark-2] == '4'){ baud = 9600; }
else if(stringBuf[mark-2] == '5'){ baud = 19200; }
else if(stringBuf[mark-2] == '6'){ baud = 38400; }
else if(stringBuf[mark-2] == '7'){ baud = 57600; }
else if(stringBuf[mark-2] == '8'){ baud = 115200; }
rprintf("baud = %d\n\r",baud);
}
}
}
}
void mode_0(void) // Auto UART mode
{
rprintf("MODE 0\n\r");
setup_uart0(baud,1);
stringSize = 512;
mode_action();
rprintf("Exit mode 0\n\r");
}
void mode_1(void)
{
rprintf("MODE 1\n\r");
setup_uart0(baud,2);
stringSize = 512;
mode_action();
}
void mode_action(void)
{
int j;
char output[1024];
char name[32];
/*An unsolved issue that I was having is that the first log does not get logged. The time stamp gets created, and the second time stamp is created
where the first log should be and the second log is after the second time stamp. All logs after this are as they should be.
Example:
"Time stamp 1:" "Time stamp 2: logged data"
"Time stamp 3: logged data"
.
.
.
"Time stamp N: logged data"
Here is how it should be:
"Time stamp 1: logged data"
"Time stamp 2: logged data"
"Time stamp 3: logged data"
.
.
.
"Time stamp N: logged data"
It has something to do with creating a new file, because the appending is working out fine
*/
while(1)
{
uint32_t ctime0_val = CTIME0;
uint32_t ctime1_val = CTIME1;
unsigned int seconds = (0x0000003f & ctime0_val); // Bit masking to read the time values from the appropriate
unsigned int minutes = (0x00003f00 & ctime0_val) >> 8; // registers, and also placing those values in the correct
unsigned int hours = (0x001f0000 & ctime0_val) >> 16; // slot to display a readable time and date
unsigned int dom = (0x0000001f & ctime1_val);
unsigned int month = (0x00000f00 & ctime1_val) >> 8;
unsigned int year = (0x0fff0000 & ctime1_val) >> 16;
string_printf(name,"%04d-%02d-%02d.txt", YEAR, MONTH, DOM); //This is the name of the file to be logged with a date stamp, but not a time stamp
//The log itself has date and time stamps, so only the date is necessary for a file name
if(!root_file_exists(name))
{
handle = root_open_new(name);
if(log_array1 == 1)
{
stringSize = sprintf(output, "%04d-%02d-%02d %02d:%02d:%02d, %s", year, month, dom, hours, minutes, seconds, (unsigned char *)RX_array1);
stat(0,ON);
if(fat_write_file(handle, output, stringSize) < 0)
{
while(1)
{
stat(0,ON);
for(j = 0; j < 500000; j++)
stat(0,OFF);
stat(1,ON);
for(j = 0; j < 500000; j++)
stat(1,OFF);
}
}
sd_raw_sync();
stat(0,OFF);
log_array1 = 0;
}
if(log_array2 == 1)
{
stringSize = sprintf(output, "%s", (unsigned char *)RX_array2);
stat(1,ON);
if(fat_write_file(handle, output, stringSize) < 0)
{
while(1)
{
stat(0,ON);
for(j = 0; j < 500000; j++)
stat(0,OFF);
stat(1,ON);
for(j = 0; j < 500000; j++)
stat(1,OFF);
}
}
sd_raw_sync();
stat(1,OFF);
log_array2 = 0;
}
fat_close_file(handle);
}
else
{
handle = root_open_append(name); //In order to append, I created the struct on line 2576 in the fat.c file that can be found in GitHub\Logomatic\Firmware\lib
if(log_array1 == 1) //My motivation for doing this can be found at this address https://forum.sparkfun.com/viewtopic.php?f=11&t=15890
{
stringSize = sprintf(output, "%04d-%02d-%02d %02d:%02d:%02d, %s", year, month, dom, hours, minutes, seconds, (unsigned char *)RX_array1);
stat(0,ON);
if(fat_write_file(handle, output, stringSize) < 0)
{
while(1)
{
stat(0,ON);
for(j = 0; j < 500000; j++)
stat(0,OFF);
stat(1,ON);
for(j = 0; j < 500000; j++)
stat(1,OFF);
}
}
sd_raw_sync();
stat(0,OFF);
log_array1 = 0;
}
if(log_array2 == 1)
{
stringSize = sprintf(output, "%s",(unsigned char *)RX_array2);
stat(1,ON);
if(fat_write_file(handle, output, stringSize) < 0)
{
while(1)
{
stat(0,ON);
for(j = 0; j < 500000; j++)
stat(0,OFF);
stat(1,ON);
for(j = 0; j < 500000; j++)
stat(1,OFF);
}
}
sd_raw_sync();
stat(1,OFF);
log_array2 = 0;
}
fat_close_file(handle);
}
}
}
void fat_initialize(void)
{
if(!sd_raw_init())
{
rprintf("SD Init Error\n\r");
while(1);
}
if(openroot())
{
rprintf("SD OpenRoot Error\n\r");
}
}
void delay_ms(int count)
{
int i;
count *= 10000;
for(i = 0; i < count; i++)
asm volatile ("nop");
}
Now, below is the code where the rprintf_devopen comes from. I honestly do not understand this function
//#########################################################################
// printf.c
//
// *** printf() based on sprintf() from gcctest9.c Volker Oth
//
// *** Changes made by Holger Klabunde
// Now takes format strings from FLASH (was into RAM ! before)
// Fixed bug for %i, %I. u_val was used before it had the right value
// Added %d, %D (is same as %i, %I)
// Support for long variables %li, %ld, %Lu, %LX ....
// %x, %X now gives upper case hex characters A,B,C,D,E,F
// Output can be redirected in a single function: myputchar()
// Make printf() smaller by commenting out a few #defines
// Added some SPACE and ZERO padding %02x or % 3u up to 9 characters
//
// Todo:
// %f, %F for floating point numbers
//
// *** Changes made by Martin Thomas for the efsl debug output:
// - removed AVR "progmem"
// - added function pointer for "putchar"
// - devopen function
//
//#########################################################################
#include <stdarg.h>
#include <string.h>
#include "rprintf.h"
//#include "system.h" //Needed for delay_ms
#define SCRATCH 12 //32Bits go up to 4GB + 1 Byte for \0
//Spare some program space by making a comment of all not used format flag lines
#define USE_LONG // %lx, %Lu and so on, else only 16 bit integer is allowed
//#define USE_OCTAL // %o, %O Octal output. Who needs this ?
#define USE_STRING // %s, %S Strings as parameters
#define USE_CHAR // %c, %C Chars as parameters
#define USE_INTEGER // %i, %I Remove this format flag. %d, %D does the same
#define USE_HEX // %x, %X Hexadezimal output
#define USE_UPPERHEX // %x, %X outputs A,B,C... else a,b,c...
#ifndef USE_HEX
#undef USE_UPPERHEX // ;)
#endif
#define USE_UPPER // uncommenting this removes %C,%D,%I,%O,%S,%U,%X and %L..
// only lowercase format flags are used
#define PADDING //SPACE and ZERO padding
static int (*putcharfunc)(int c);
void rprintf_devopen( int(*put)(int) )
{
putcharfunc = put;
}
static void myputchar(unsigned char c)
{
if(c == '\n') putcharfunc('\r');
putcharfunc(c);
}
void rprintf(char const *format, ...)
{
unsigned char scratch[SCRATCH];
unsigned char format_flag;
unsigned short base;
unsigned char *ptr;
unsigned char issigned=0;
va_list ap;
#ifdef USE_LONG
// #warning "use long"
unsigned char islong=0;
unsigned long u_val=0;
long s_val=0;
#else
unsigned int u_val=0;
int s_val=0;
#endif
unsigned char fill;
unsigned char width;
va_start (ap, format);
for (;;)
{
delay_ms(1); //Added for VCOM testing - without it, rprintf will overrun the VCOM buffer causing it to crash
while ((format_flag = *(format++)) != '%')
{ // Until '%' or '\0'
if (!format_flag){va_end (ap); return;}
myputchar(format_flag);
}
issigned=0; //default unsigned
base = 10;
format_flag = *format++; //get char after '%'
#ifdef PADDING
width=0; //no formatting
fill=0; //no formatting
if(format_flag=='0' || format_flag==' ') //SPACE or ZERO padding ?
{
fill=format_flag;
format_flag = *format++; //get char after padding char
if(format_flag>='0' && format_flag<='9')
{
width=format_flag-'0';
format_flag = *format++; //get char after width char
}
}
#endif
#ifdef USE_LONG
islong=0; //default int value
#ifdef USE_UPPER
if(format_flag=='l' || format_flag=='L') //Long value
#else
if(format_flag=='l') //Long value
#endif
{
islong=1;
format_flag = *format++; //get char after 'l' or 'L'
}
#endif
switch (format_flag)
{
#ifdef USE_CHAR
case 'c':
#ifdef USE_UPPER
case 'C':
#endif
format_flag = va_arg(ap,int);
// no break -> run into default
#endif
default:
myputchar(format_flag);
continue;
#ifdef USE_STRING
#ifdef USE_UPPER
case 'S':
#endif
case 's':
ptr = (unsigned char*)va_arg(ap,char *);
while(*ptr) { myputchar(*ptr); ptr++; }
continue;
#endif
#ifdef USE_OCTAL
case 'o':
#ifdef USE_UPPER
case 'O':
#endif
base = 8;
myputchar('0');
goto CONVERSION_LOOP;
#endif
#ifdef USE_INTEGER //don't use %i, is same as %d
case 'i':
#ifdef USE_UPPER
case 'I':
#endif
#endif
case 'd':
#ifdef USE_UPPER
case 'D':
#endif
issigned=1;
// no break -> run into next case
case 'u':
#ifdef USE_UPPER
case 'U':
#endif
//don't insert some case below this if USE_HEX is undefined !
//or put goto CONVERSION_LOOP; before next case.
#ifdef USE_HEX
goto CONVERSION_LOOP;
case 'x':
#ifdef USE_UPPER
case 'X':
#endif
base = 16;
#endif
CONVERSION_LOOP:
if(issigned) //Signed types
{
#ifdef USE_LONG
if(islong) { s_val = va_arg(ap,long); }
else { s_val = va_arg(ap,int); }
#else
s_val = va_arg(ap,int);
#endif
if(s_val < 0) //Value negativ ?
{
s_val = - s_val; //Make it positiv
myputchar('-'); //Output sign
}
u_val = (unsigned long)s_val;
}
else //Unsigned types
{
#ifdef USE_LONG
if(islong) { u_val = va_arg(ap,unsigned long); }
else { u_val = va_arg(ap,unsigned int); }
#else
u_val = va_arg(ap,unsigned int);
#endif
}
ptr = scratch + SCRATCH;
*--ptr = 0;
do
{
char ch = u_val % base + '0';
#ifdef USE_HEX
if (ch > '9')
{
ch += 'a' - '9' - 1;
#ifdef USE_UPPERHEX
ch-=0x20;
#endif
}
#endif
*--ptr = ch;
u_val /= base;
#ifdef PADDING
if(width) width--; //calculate number of padding chars
#endif
}
while (u_val);
#ifdef PADDING
while(width--) *--ptr = fill; //insert padding chars
#endif
while(*ptr) { myputchar(*ptr); ptr++; }
}
}
}
Finally here is the code with the putchar functions.
/******************************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright KEIL ELEKTRONIK GmbH 2002-2004 */
/******************************************************************************/
/* */
/* SERIAL.C: Low Level Serial Routines */
/* modified and extended by Martin Thomas */
/* */
/******************************************************************************/
#include "LPC214x.h"
#include "target.h"
#include "serial.h"
#define CR 0x0D
/* Initialize Serial Interface UART0 */
void init_serial0 ( unsigned long baudrate )
{
unsigned long Fdiv;
PINSEL0 = 0x00000005; /* Enable RxD0 and TxD0 */
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( Fcclk / 16 ) / baudrate ; /* baud rate */
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03; /* DLAB = 0 */
}
/* Initialize Serial Interface UART0 */
void init_serial1 ( unsigned long baudrate )
{
unsigned long Fdiv;
PINSEL0 |= (1<<16) | (1<<18); /* Enable RxD1 and TxD1 */
U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( Fcclk / 16 ) / baudrate ; /* baud rate */
U1DLM = Fdiv / 256;
U1DLL = Fdiv % 256;
U1LCR = 0x03; /* DLAB = 0 */
}
// Write character to Serial Port 0 with \n -> \r\n
int putchar_serial0 (int ch)
{
if (ch == '\n')
{
while (!(U0LSR & 0x20));
U0THR = CR; // output CR
}
while (!(U0LSR & 0x20));
return (U0THR = ch);
}
// Write character to Serial Port 0 without \n -> \r\n
int putc_serial0 (int ch)
{
while (!(U0LSR & 0x20));
return (U0THR = ch);
}
// Write character to Serial Port 1 without \n -> \r\n
int putc_serial1 (int ch)
{
while (!(U1LSR & 0x20));
return (U1THR = ch);
}
void putstring_serial0 (const char *string)
{
char ch;
while ((ch = *string))
{
putchar_serial0(ch);
string++;
}
}
// Read character from Serial Port
int getkey_serial0 (void)
{
if (U0LSR & 0x01)
{
return (U0RBR);
}
else
{
return 0;
}
}
// Read character from Serial Port
int getc0 (void)
{
while ( (U0LSR & 0x01) == 0 ); //Wait for character
return U0RBR;
}
Now, keep in mind that my programming skills are mediocre at best. Before attempting this project I took a C class for non computer science majors. I have learned a ton trying to tackle this code, but this problem has plagued me for some time now. Any help would be much appreciated.