Sign in

username:

password:



Not a member?

Search 68hc12



Search tips

Subscribe to 68hc12



68hc12 by Keywords

68HC1 | 812A4 | 9S12DP256 | Bootloader | CodeWarrior | D60A | Debugger | DP256 | ECT | EEPROM | EVB | Flash | HC1 | HCS12 | I2C | IAR | ICC1 | Interrupts | LCD | M68KIT912DP256 | MC9S12DP256 | MC9S12DP256B | Metrowerks | Motor | MSCAN | Multilink | PLL | Quadrature | SDI | SPI | Transceiver | XFC


Ads

Discussion Groups

See Also

DSPFPGAElectronics

Discussion Groups | 68HC12 | Dragon Board 12 Serial Communication C code Help


Advertise Here

Join our technical discussions about Freescale Microcontrollers: M68HC12. (Freescale Semiconductor is a Subsidiary of Motorola).

Dragon Board 12 Serial Communication C code Help - zach...@gmail.com - Oct 26 16:27:01 2009

Hello all, I am hoping someone has some incite as to what I am doing wrong here, I figure it is a small problem but I am out of ideas. This is just a test to figure out how to pass char * through methods. The code should print Hello World to the serial port which it does, then print tes repeatedly, which it does not, rather the output is as follows:

Hello World"""""""""""""""""""""""""""""""""""""""""""""""""""""""
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Here is the code, also below is the sci.c and sci.h that do the actually serial communication.

Thank You in advanced !

Zach Long

MAIN:

#include "sci.h"

int main(void);
void encode(char *out);

int main(void)
{
char* head = "Hello World"; // declare first print statement
char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char

SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD
SCI_OutStatus(1); // Is it clear to send (buffer empty)
SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!)

while(1)
{
if(SCI_OutStatus(0))// Is it clear to send (buffer empty)
{
encode(outData);//,out.throt,out.heading); // build output
SCI_OutString(outData,0); // print out put to serial port
}
}
return 0;
}

void encode(char *out) // take in pointer and fill with chars
{
out[0] = 't';
out[1] = 'e';
out[2] = 's';
out[3] = 0;
}

SCI include:

// filename ******************* SCI.H **************************
// Jonathan W. Valvano 1/29/04

// This example accompanies the books
// "Embedded Microcomputer Systems: Real Time Interfacing",
// Brooks-Cole, copyright (c) 2000,
// "Introduction to Embedded Microcomputer Systems:
// Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002

// Copyright 2004 by Jonathan W. Valvano, v...@mail.utexas.edu
// You may use, edit, run or distribute this file
// as long as the above copyright notice remains
// Modified by EE345L students Charlie Gough && Matt Hawk
// Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
// Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600 BAUD, use of both serial ports enabled)

//How To
/*
Each method has an unsigned int port parameter, this specifices the serial port
the method will act on. Dragon Board 12: Serial port under LCD (top) = 0, Serial port near power plug (bottom) = 1
*/

// standard ASCII symbols
#define CR 0x0D
#define LF 0x0A
#define BS 0x08
#define ESC 0x1B
#define SP 0x20
#define DEL 0x7F

//-------------------------SCI_Init------------------------
//-------------------------SCI_Init------------------------
// Initialize Serial port SCI
// Input: baudRate is tha baud rate in bits/sec
// Output: none
// SCIBDL = 24000000/(16 x BR)
// baudRate = 2400 bits/sec SCIBDL=625
// baudRate = 4800 bits/sec SCIBDL=313
// baudRate = 9600 bits/sec SCIBDL=156
// baudRate = 19200 bits/sec SCIBDL=78
// assumes a module clock frequency of 4 MHz
// sets baudRate to 9600
void SCI_Init(unsigned short baudRate,unsigned int port);

//-------------------------SCI_InStatus--------------------------
// Checks if new input is ready, TRUE if new input is ready
// Input: unsigned int port
// Output: TRUE if a call to InChar will return right away with data
// FALSE if a call to InChar will wait for input
char SCI_InStatus(unsigned int port);

//-------------------------SCI_InChar------------------------
// Wait for new serial port input, busy-waiting synchronization
// Input: unsigned int port
// Output: ASCII code for key typed
char SCI_InChar(unsigned int port);

void SCI_InString(char* string,unsigned short max,unsigned int port); // Reads in a String of max length

//----------------------SCI_InUDec-------------------------------
// InUDec accepts ASCII input in unsigned decimal format
// and converts to a 16 bit unsigned number
// valid range is 0 to 65535
// Input: unsigned int port
// Output: 16-bit unsigned number
// If you enter a number above 65535, it will truncate without an error
// Backspace will remove last digit typed
unsigned short SCI_InUDec(unsigned int port);

//---------------------SCI_InUHex----------------------------------------
// Accepts ASCII input in unsigned hexadecimal (base 16) format
// Input: unsigned int port
// Output: 16-bit unsigned number
// No '$' or '0x' need be entered, just the 1 to 4 hex digits
// It will convert lower case a-f to uppercase A-F
// and converts to a 16 bit unsigned number
// value range is 0 to FFFF
// If you enter a number above FFFF, it will truncate without an error
// Backspace will remove last digit typed
unsigned short SCI_InUHex(unsigned int port);

//-----------------------SCI_OutStatus----------------------------
// Checks if output data buffer is empty, TRUE if empty
// Input: unsigned int port
// Output: TRUE if a call to OutChar will output and return right away
// FALSE if a call to OutChar will wait for output to be ready
char SCI_OutStatus(unsigned int port);

//-------------------------SCI_OutChar------------------------
// Wait for buffer to be empty, output 8-bit to serial port
// busy-waiting synchronization
// Input: 8-bit data to be transferred, unsigned int port
// Output: none
void SCI_OutChar(char data,unsigned int port);

//-----------------------SCI_OutUDec-----------------------
// Output a 16-bit number in unsigned decimal format
// Input: 16-bit number to be transferred, unsigned int port
// Output: none
// Variable format 1-5 digits with no space before or after
void SCI_OutUDec(unsigned short,unsigned int port);

//-------------------------SCI_OutString------------------------
// Output String (NULL termination), busy-waiting synchronization
// Input: pointer to a NULL-terminated string to be transferred, unsigned int port
// Output: none
void SCI_OutString(char *pt,unsigned int port);

//--------------------------SCI_OutUHex----------------------------
// Output a 16 bit number in unsigned hexadecimal format
// Input: 16-bit number to be transferred, unsigned int port
// Output: none
// Variable format 1 to 4 digits with no space before or after
void SCI_OutUHex(unsigned short,unsigned int port);

// filename *************** SCI.C ******************************
// Simple I/O routines to 9S12C32 serial port
// Jonathan W. Valvano 1/29/04

// This example accompanies the books
// "Embedded Microcomputer Systems: Real Time Interfacing",
// Brooks-Cole, copyright (c) 2000,
// "Introduction to Embedded Microcomputer Systems:
// Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002

// Copyright 2004 by Jonathan W. Valvano, v...@mail.utexas.edu
// You may use, edit, run or distribute this file
// as long as the above copyright notice remains
// Modified by EE345L students Charlie Gough && Matt Hawk
// Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
// Modified by Steven Lamb April 28, 2004 (minor changes for g++)
// Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use of both serial ports enabled)
//How To
/*

*/

#include "hcs12.h" // io register map
#include "SCI.h"
#define RDRF 0x20 // Receive Data Register Full Bit
#define TDRE 0x80 // Transmit Data Register Empty Bit
//-------------------------SCI_Init------------------------
// Initialize Serial port SCI
// Input: baudRate is tha baud rate in bits/sec
// Output: none
// SCIBDL = 24000000/(16 x BR)
// baudRate = 2400 bits/sec SCIBDL=625
// baudRate = 4800 bits/sec SCIBDL=313
// baudRate = 9600 bits/sec SCIBDL=156
// baudRate = 19200 bits/sec SCIBDL=78
// assumes a module clock frequency of 4 MHz
// sets baudRate to 9600
void SCI_Init(unsigned short baudRate, unsigned int port)
{
switch(port)
{
case 0:
{
SCI0BDH = 0;
switch(baudRate)
{
case 2400: SCI0BDL=625; break;
case 4800: SCI0BDL=313; break;
case 9600: SCI0BDL=156; break;
case 19200: SCI0BDL=78; break;
default: SCI0BDL = 156 ; // 9600
}
break;

SCI0CR1 = 0;
/* bit value meaning
7 0 LOOPS, no looping, normal
6 0 WOMS, normal high/low outputs
5 0 RSRC, not appliable with LOOPS=0
4 0 M, 1 start, 8 data, 1 stop
3 0 WAKE, wake by idle (not applicable)
2 0 ILT, short idle time (not applicable)
1 0 PE, no parity
0 0 PT, parity type (not applicable with PE=0)
*/

SCI0CR2 = 0x0C;
/* bit value meaning
7 0 TIE, no transmit interrupts on TDRE
6 0 TCIE, no transmit interrupts on TC
5 0 RIE, no receive interrupts on RDRF
4 0 ILIE, no interrupts on idle
3 1 TE, enable transmitter
2 1 RE, enable receiver
1 0 RWU, no receiver wakeup
0 0 SBK, no send break
*/
break;
}
case 1:
{
SCI1BDH = 0;
switch(baudRate)
{
case 2400: SCI1BDL=625; break;
case 4800: SCI1BDL=313; break;
case 9600: SCI1BDL=156; break;
case 19200: SCI1BDL=78; break;
default: SCI1BDL = 156 ; // 9600
}
break;

SCI1CR1 = 0;
/* bit value meaning
7 0 LOOPS, no looping, normal
6 0 WOMS, normal high/low outputs
5 0 RSRC, not appliable with LOOPS=0
4 0 M, 1 start, 8 data, 1 stop
3 0 WAKE, wake by idle (not applicable)
2 0 ILT, short idle time (not applicable)
1 0 PE, no parity
0 0 PT, parity type (not applicable with PE=0)
*/

SCI1CR2 = 0x0C;
/* bit value meaning
7 0 TIE, no transmit interrupts on TDRE
6 0 TCIE, no transmit interrupts on TC
5 0 RIE, no receive interrupts on RDRF
4 0 ILIE, no interrupts on idle
3 1 TE, enable transmitter
2 1 RE, enable receiver
1 0 RWU, no receiver wakeup
0 0 SBK, no send break
*/
break;
}
}
}

//-------------------------SCI_InChar------------------------
// Wait for new serial port input, busy-waiting synchronization
// Input: int port
// Output: ASCII code for key typed
char SCI_InChar(unsigned int port)
{
switch(port)
{
case 0:
while((SCI0SR1 & RDRF) == 0){};
return(SCI0DRL);
break;
case 1:
while((SCI1SR1 & RDRF) == 0){};
return(SCI1DRL);
break;
}
}

//-------------------------SCI_OutChar------------------------
// Wait for buffer to be empty, output 8-bit to serial port
// busy-waiting synchronization
// Input: 8-bit data to be transferred
// Output: none
void SCI_OutChar(char data,unsigned int port)
{
switch(port)
{
case 0:
while((SCI0SR1 & TDRE) == 0){};
SCI0DRL = data;
break;
case 1:
while((SCI1SR1 & TDRE) == 0){};
SCI1DRL = data;
break;
}
}

//-------------------------SCI_InStatus--------------------------
// Checks if new input is ready, TRUE if new input is ready
// Input: unsigned int port
// Output: TRUE if a call to InChar will return right away with data
// FALSE if a call to InChar will wait for input
char SCI_InStatus(unsigned int port)
{
switch(port)
{
case 0:
return(SCI0SR1 & RDRF);break;
case 1:
return(SCI1SR1 & RDRF);break;
}
}
//-----------------------SCI_OutStatus----------------------------
// Checks if output data buffer is empty, TRUE if empty
// Input: unsigned int port
// Output: TRUE if a call to OutChar will output and return right away
// FALSE if a call to OutChar will wait for output to be ready
char SCI_OutStatus(unsigned int port)
{
switch(port)
{
case 0:
return(SCI0SR1 & TDRE);
break;
case 1:
return(SCI1SR1 & TDRE);
break;
}
}
//-------------------------SCI_OutString------------------------
// Output String (NULL termination), busy-waiting synchronization
// Input: pointer to a NULL-terminated string to be transferred, unsigned int port
// Output: none
void SCI_OutString(char *pt,unsigned int port)
{
while(*pt){
SCI_OutChar(*pt,port);
pt++;
}
}

//----------------------SCI_InUDec-------------------------------
// InUDec accepts ASCII input in unsigned decimal format
// and converts to a 16 bit unsigned number
// valid range is 0 to 65535
// Input: unsigned int port
// Output: 16-bit unsigned number
// If you enter a number above 65535, it will truncate without an error
// Backspace will remove last digit typed
unsigned short SCI_InUDec(unsigned int port)
{
unsigned short number=0, length=0;
char character;
character = SCI_InChar(port);
while(character!=CR) // accepts until carriage return input
{
// The next line checks that the input is a digit, 0-9.
// If the character is not 0-9, it is ignored and not echoed
if((character>='0') && (character<='9'))
{
number = 10*number+(character-'0'); // this line overflows if above 65535
length++;
SCI_OutChar(character,port);
}
// If the input is a backspace, then the return number is
// changed and a backspace is outputted to the screen
else if((character==BS) && length)
{
number /= 10;
length--;
SCI_OutChar(character,port);
}
character = SCI_InChar(port);
}
return number;
}
//-----------------------SCI_OutUDec-----------------------
// Output a 16-bit number in unsigned decimal format
// Input: 16-bit number to be transferred, unsigned int port
// Output: none
// Variable format 1-5 digits with no space before or after
void SCI_OutUDec(unsigned short n,unsigned int port)
{
// This function uses recursion to convert decimal number
// of unspecified length as an ASCII string
if(n >= 10){
SCI_OutUDec(n/10,port);
n = n%10;
}
SCI_OutChar(n+'0',port); /* n is between 0 and 9 */
}

//---------------------SCI_InUHex----------------------------------------
// Accepts ASCII input in unsigned hexadecimal (base 16) format
// Input: unsigned int port
// Output: 16-bit unsigned number
// No '$' or '0x' need be entered, just the 1 to 4 hex digits
// It will convert lower case a-f to uppercase A-F
// and converts to a 16 bit unsigned number
// value range is 0 to FFFF
// If you enter a number above FFFF, it will truncate without an error
// Backspace will remove last digit typed
unsigned short SCI_InUHex(unsigned int port){
unsigned short number=0, digit, length=0;
char character;
character = SCI_InChar(port);
while(character!=CR){
digit = 0x10; // assume bad
if((character>='0') && (character<='9')){
digit = character-'0';
}
else if((character>='A') && (character<='F')){
digit = (character-'A')+0xA;
}
else if((character>='a') && (character<='f')){
digit = (character-'a')+0xA;
}
// If the character is not 0-9 or A-F, it is ignored and not echoed
if(digit<=0xF ){
number = number*0x10+digit;
length++;
SCI_OutChar(character,port);
}
// Backspace outputted and return value changed if a backspace is inputted
else if(character==BS && length){
number /=0x10;
length--;
SCI_OutChar(character,port);
}
character = SCI_InChar(port);
}
return number;
}

//--------------------------SCI_OutUHex----------------------------
// Output a 16 bit number in unsigned hexadecimal format
// Input: 16-bit number to be transferred, unsigned int port
// Output: none
// Variable format 1 to 4 digits with no space before or after
void SCI_OutUHex(unsigned short number,unsigned int port){
// This function uses recursion to convert the number of
// unspecified length as an ASCII string
if(number>=0x10) {
SCI_OutUHex(number/0x10,port);
SCI_OutUHex(number%0x10,port);
}
else if(number<0xA){
SCI_OutChar(number+'0',port);
}
else{
SCI_OutChar((number-0x0A)+'A',port);
}
}

//------------------------SCI_InString------------------------
// This function accepts ASCII characters from the serial port
// and adds them to a string until a carriage return is inputted
// or until max length of the string is reached.
// It echoes each character as it is inputted.
// If a backspace is inputted, the string is modified
// and the backspace is echoed
// InString terminates the string with a null character
// -- Modified by Agustinus Darmawan + Mingjie Qiu --
void SCI_InString(char *string,unsigned short max,unsigned int port)
{
int length=0;
char character;
character = SCI_InChar(port);
while(character!=CR)
{
if(character==BS)
{
if(length)
{
string--;
length--;
SCI_OutChar(BS,port);
}
}
else if(length {
*string++=character;
length++;
SCI_OutChar(character,port);
}
character = SCI_InChar(port);
}
*string = 0;
}

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )


Re: Dragon Board 12 Serial Communication C code Help - Edward Karpicz - Oct 27 0:52:13 2009

Probably malloc didn't succeed

char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char

BTW comment is wrong, should be make room for 5 pointers to char

Edward

----- Original Message -----
From:
To: <6...@yahoogroups.com>
Sent: Monday, October 26, 2009 10:26 PM
Subject: [68HC12] Dragon Board 12 Serial Communication C code Help
> Hello all, I am hoping someone has some incite as to what I am doing wrong
> here, I figure it is a small problem but I am out of ideas. This is just a
> test to figure out how to pass char * through methods. The code should
> print Hello World to the serial port which it does, then print tes
> repeatedly, which it does not, rather the output is as follows:
>
> Hello World"""""""""""""""""""""""""""""""""""""""""""""""""""""""
> """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
>
> Here is the code, also below is the sci.c and sci.h that do the actually
> serial communication.
>
> Thank You in advanced !
>
> Zach Long
>
> MAIN:
>
> #include "sci.h"
>
> int main(void);
> void encode(char *out);
>
> int main(void)
> {
> char* head = "Hello World"; // declare first print statement
> char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char
>
> SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD
> SCI_OutStatus(1); // Is it clear to send (buffer empty)
> SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!)
>
> while(1)
> {
> if(SCI_OutStatus(0))// Is it clear to send (buffer empty)
> {
> encode(outData);//,out.throt,out.heading); // build output
> SCI_OutString(outData,0); // print out put to serial port
> }
> }
> return 0;
> }
>
> void encode(char *out) // take in pointer and fill with chars
> {
> out[0] = 't';
> out[1] = 'e';
> out[2] = 's';
> out[3] = 0;
> }
>
> SCI include:
>
> // filename ******************* SCI.H **************************
> // Jonathan W. Valvano 1/29/04
>
> // This example accompanies the books
> // "Embedded Microcomputer Systems: Real Time Interfacing",
> // Brooks-Cole, copyright (c) 2000,
> // "Introduction to Embedded Microcomputer Systems:
> // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002
>
> // Copyright 2004 by Jonathan W. Valvano, v...@mail.utexas.edu
> // You may use, edit, run or distribute this file
> // as long as the above copyright notice remains
> // Modified by EE345L students Charlie Gough && Matt Hawk
> // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
> // Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600
> BAUD, use of both serial ports enabled)
>
> //How To
> /*
> Each method has an unsigned int port parameter, this specifices the
> serial port
> the method will act on. Dragon Board 12: Serial port under LCD (top) =
> 0, Serial port near power plug (bottom) = 1
> */
>
> // standard ASCII symbols
> #define CR 0x0D
> #define LF 0x0A
> #define BS 0x08
> #define ESC 0x1B
> #define SP 0x20
> #define DEL 0x7F
>
> //-------------------------SCI_Init------------------------
> //-------------------------SCI_Init------------------------
> // Initialize Serial port SCI
> // Input: baudRate is tha baud rate in bits/sec
> // Output: none
> // SCIBDL = 24000000/(16 x BR)
> // baudRate = 2400 bits/sec SCIBDL=625
> // baudRate = 4800 bits/sec SCIBDL=313
> // baudRate = 9600 bits/sec SCIBDL=156
> // baudRate = 19200 bits/sec SCIBDL=78
> // assumes a module clock frequency of 4 MHz
> // sets baudRate to 9600
> void SCI_Init(unsigned short baudRate,unsigned int port);
>
> //-------------------------SCI_InStatus--------------------------
> // Checks if new input is ready, TRUE if new input is ready
> // Input: unsigned int port
> // Output: TRUE if a call to InChar will return right away with data
> // FALSE if a call to InChar will wait for input
> char SCI_InStatus(unsigned int port);
>
> //-------------------------SCI_InChar------------------------
> // Wait for new serial port input, busy-waiting synchronization
> // Input: unsigned int port
> // Output: ASCII code for key typed
> char SCI_InChar(unsigned int port);
>
> void SCI_InString(char* string,unsigned short max,unsigned int port); //
> Reads in a String of max length
>
> //----------------------SCI_InUDec-------------------------------
> // InUDec accepts ASCII input in unsigned decimal format
> // and converts to a 16 bit unsigned number
> // valid range is 0 to 65535
> // Input: unsigned int port
> // Output: 16-bit unsigned number
> // If you enter a number above 65535, it will truncate without an error
> // Backspace will remove last digit typed
> unsigned short SCI_InUDec(unsigned int port);
>
> //---------------------SCI_InUHex----------------------------------------
> // Accepts ASCII input in unsigned hexadecimal (base 16) format
> // Input: unsigned int port
> // Output: 16-bit unsigned number
> // No '$' or '0x' need be entered, just the 1 to 4 hex digits
> // It will convert lower case a-f to uppercase A-F
> // and converts to a 16 bit unsigned number
> // value range is 0 to FFFF
> // If you enter a number above FFFF, it will truncate without an error
> // Backspace will remove last digit typed
> unsigned short SCI_InUHex(unsigned int port);
>
> //-----------------------SCI_OutStatus----------------------------
> // Checks if output data buffer is empty, TRUE if empty
> // Input: unsigned int port
> // Output: TRUE if a call to OutChar will output and return right away
> // FALSE if a call to OutChar will wait for output to be ready
> char SCI_OutStatus(unsigned int port);
>
> //-------------------------SCI_OutChar------------------------
> // Wait for buffer to be empty, output 8-bit to serial port
> // busy-waiting synchronization
> // Input: 8-bit data to be transferred, unsigned int port
> // Output: none
> void SCI_OutChar(char data,unsigned int port);
>
> //-----------------------SCI_OutUDec-----------------------
> // Output a 16-bit number in unsigned decimal format
> // Input: 16-bit number to be transferred, unsigned int port
> // Output: none
> // Variable format 1-5 digits with no space before or after
> void SCI_OutUDec(unsigned short,unsigned int port);
>
> //-------------------------SCI_OutString------------------------
> // Output String (NULL termination), busy-waiting synchronization
> // Input: pointer to a NULL-terminated string to be transferred, unsigned
> int port
> // Output: none
> void SCI_OutString(char *pt,unsigned int port);
>
> //--------------------------SCI_OutUHex----------------------------
> // Output a 16 bit number in unsigned hexadecimal format
> // Input: 16-bit number to be transferred, unsigned int port
> // Output: none
> // Variable format 1 to 4 digits with no space before or after
> void SCI_OutUHex(unsigned short,unsigned int port);
>
> // filename *************** SCI.C ******************************
> // Simple I/O routines to 9S12C32 serial port
> // Jonathan W. Valvano 1/29/04
>
> // This example accompanies the books
> // "Embedded Microcomputer Systems: Real Time Interfacing",
> // Brooks-Cole, copyright (c) 2000,
> // "Introduction to Embedded Microcomputer Systems:
> // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002
>
> // Copyright 2004 by Jonathan W. Valvano, v...@mail.utexas.edu
> // You may use, edit, run or distribute this file
> // as long as the above copyright notice remains
> // Modified by EE345L students Charlie Gough && Matt Hawk
> // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
> // Modified by Steven Lamb April 28, 2004 (minor changes for g++)
> // Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use
> of both serial ports enabled)
> //How To
> /*
>
> */
>
> #include "hcs12.h" // io register map
> #include "SCI.h"
> #define RDRF 0x20 // Receive Data Register Full Bit
> #define TDRE 0x80 // Transmit Data Register Empty Bit
> //-------------------------SCI_Init------------------------
> // Initialize Serial port SCI
> // Input: baudRate is tha baud rate in bits/sec
> // Output: none
> // SCIBDL = 24000000/(16 x BR)
> // baudRate = 2400 bits/sec SCIBDL=625
> // baudRate = 4800 bits/sec SCIBDL=313
> // baudRate = 9600 bits/sec SCIBDL=156
> // baudRate = 19200 bits/sec SCIBDL=78
> // assumes a module clock frequency of 4 MHz
> // sets baudRate to 9600
> void SCI_Init(unsigned short baudRate, unsigned int port)
> {
> switch(port)
> {
> case 0:
> {
> SCI0BDH = 0;
> switch(baudRate)
> {
> case 2400: SCI0BDL=625; break;
> case 4800: SCI0BDL=313; break;
> case 9600: SCI0BDL=156; break;
> case 19200: SCI0BDL=78; break;
> default: SCI0BDL = 156 ; // 9600
> }
> break;
>
> SCI0CR1 = 0;
> /* bit value meaning
> 7 0 LOOPS, no looping, normal
> 6 0 WOMS, normal high/low outputs
> 5 0 RSRC, not appliable with LOOPS=0
> 4 0 M, 1 start, 8 data, 1 stop
> 3 0 WAKE, wake by idle (not applicable)
> 2 0 ILT, short idle time (not applicable)
> 1 0 PE, no parity
> 0 0 PT, parity type (not applicable with PE=0)
> */
>
> SCI0CR2 = 0x0C;
> /* bit value meaning
> 7 0 TIE, no transmit interrupts on TDRE
> 6 0 TCIE, no transmit interrupts on TC
> 5 0 RIE, no receive interrupts on RDRF
> 4 0 ILIE, no interrupts on idle
> 3 1 TE, enable transmitter
> 2 1 RE, enable receiver
> 1 0 RWU, no receiver wakeup
> 0 0 SBK, no send break
> */
> break;
> }
> case 1:
> {
> SCI1BDH = 0;
> switch(baudRate)
> {
> case 2400: SCI1BDL=625; break;
> case 4800: SCI1BDL=313; break;
> case 9600: SCI1BDL=156; break;
> case 19200: SCI1BDL=78; break;
> default: SCI1BDL = 156 ; // 9600
> }
> break;
>
> SCI1CR1 = 0;
> /* bit value meaning
> 7 0 LOOPS, no looping, normal
> 6 0 WOMS, normal high/low outputs
> 5 0 RSRC, not appliable with LOOPS=0
> 4 0 M, 1 start, 8 data, 1 stop
> 3 0 WAKE, wake by idle (not applicable)
> 2 0 ILT, short idle time (not applicable)
> 1 0 PE, no parity
> 0 0 PT, parity type (not applicable with PE=0)
> */
>
> SCI1CR2 = 0x0C;
> /* bit value meaning
> 7 0 TIE, no transmit interrupts on TDRE
> 6 0 TCIE, no transmit interrupts on TC
> 5 0 RIE, no receive interrupts on RDRF
> 4 0 ILIE, no interrupts on idle
> 3 1 TE, enable transmitter
> 2 1 RE, enable receiver
> 1 0 RWU, no receiver wakeup
> 0 0 SBK, no send break
> */
> break;
> }
> }
> }
> //-------------------------SCI_InChar------------------------
> // Wait for new serial port input, busy-waiting synchronization
> // Input: int port
> // Output: ASCII code for key typed
> char SCI_InChar(unsigned int port)
> {
> switch(port)
> {
> case 0:
> while((SCI0SR1 & RDRF) == 0){};
> return(SCI0DRL);
> break;
> case 1:
> while((SCI1SR1 & RDRF) == 0){};
> return(SCI1DRL);
> break;
> }
> }
>
> //-------------------------SCI_OutChar------------------------
> // Wait for buffer to be empty, output 8-bit to serial port
> // busy-waiting synchronization
> // Input: 8-bit data to be transferred
> // Output: none
> void SCI_OutChar(char data,unsigned int port)
> {
> switch(port)
> {
> case 0:
> while((SCI0SR1 & TDRE) == 0){};
> SCI0DRL = data;
> break;
> case 1:
> while((SCI1SR1 & TDRE) == 0){};
> SCI1DRL = data;
> break;
> }
> }
>
> //-------------------------SCI_InStatus--------------------------
> // Checks if new input is ready, TRUE if new input is ready
> // Input: unsigned int port
> // Output: TRUE if a call to InChar will return right away with data
> // FALSE if a call to InChar will wait for input
> char SCI_InStatus(unsigned int port)
> {
> switch(port)
> {
> case 0:
> return(SCI0SR1 & RDRF);break;
> case 1:
> return(SCI1SR1 & RDRF);break;
> }
> }
> //-----------------------SCI_OutStatus----------------------------
> // Checks if output data buffer is empty, TRUE if empty
> // Input: unsigned int port
> // Output: TRUE if a call to OutChar will output and return right away
> // FALSE if a call to OutChar will wait for output to be ready
> char SCI_OutStatus(unsigned int port)
> {
> switch(port)
> {
> case 0:
> return(SCI0SR1 & TDRE);
> break;
> case 1:
> return(SCI1SR1 & TDRE);
> break;
> }
> }
> //-------------------------SCI_OutString------------------------
> // Output String (NULL termination), busy-waiting synchronization
> // Input: pointer to a NULL-terminated string to be transferred, unsigned
> int port
> // Output: none
> void SCI_OutString(char *pt,unsigned int port)
> {
> while(*pt){
> SCI_OutChar(*pt,port);
> pt++;
> }
> }
>
> //----------------------SCI_InUDec-------------------------------
> // InUDec accepts ASCII input in unsigned decimal format
> // and converts to a 16 bit unsigned number
> // valid range is 0 to 65535
> // Input: unsigned int port
> // Output: 16-bit unsigned number
> // If you enter a number above 65535, it will truncate without an error
> // Backspace will remove last digit typed
> unsigned short SCI_InUDec(unsigned int port)
> {
> unsigned short number=0, length=0;
> char character;
> character = SCI_InChar(port);
> while(character!=CR) // accepts until carriage return input
> {
> // The next line checks that the input is a digit, 0-9.
> // If the character is not 0-9, it is ignored and not echoed
> if((character>='0') && (character<='9'))
> {
> number = 10*number+(character-'0'); // this line overflows if
> above 65535
> length++;
> SCI_OutChar(character,port);
> }
> // If the input is a backspace, then the return number is
> // changed and a backspace is outputted to the screen
> else if((character==BS) && length)
> {
> number /= 10;
> length--;
> SCI_OutChar(character,port);
> }
> character = SCI_InChar(port);
> }
> return number;
> }
> //-----------------------SCI_OutUDec-----------------------
> // Output a 16-bit number in unsigned decimal format
> // Input: 16-bit number to be transferred, unsigned int port
> // Output: none
> // Variable format 1-5 digits with no space before or after
> void SCI_OutUDec(unsigned short n,unsigned int port)
> {
> // This function uses recursion to convert decimal number
> // of unspecified length as an ASCII string
> if(n >= 10){
> SCI_OutUDec(n/10,port);
> n = n%10;
> }
> SCI_OutChar(n+'0',port); /* n is between 0 and 9 */
> }
>
> //---------------------SCI_InUHex----------------------------------------
> // Accepts ASCII input in unsigned hexadecimal (base 16) format
> // Input: unsigned int port
> // Output: 16-bit unsigned number
> // No '$' or '0x' need be entered, just the 1 to 4 hex digits
> // It will convert lower case a-f to uppercase A-F
> // and converts to a 16 bit unsigned number
> // value range is 0 to FFFF
> // If you enter a number above FFFF, it will truncate without an error
> // Backspace will remove last digit typed
> unsigned short SCI_InUHex(unsigned int port){
> unsigned short number=0, digit, length=0;
> char character;
> character = SCI_InChar(port);
> while(character!=CR){
> digit = 0x10; // assume bad
> if((character>='0') && (character<='9')){
> digit = character-'0';
> }
> else if((character>='A') && (character<='F')){
> digit = (character-'A')+0xA;
> }
> else if((character>='a') && (character<='f')){
> digit = (character-'a')+0xA;
> }
> // If the character is not 0-9 or A-F, it is ignored and not echoed
> if(digit<=0xF ){
> number = number*0x10+digit;
> length++;
> SCI_OutChar(character,port);
> }
> // Backspace outputted and return value changed if a backspace is inputted
> else if(character==BS && length){
> number /=0x10;
> length--;
> SCI_OutChar(character,port);
> }
> character = SCI_InChar(port);
> }
> return number;
> }
>
> //--------------------------SCI_OutUHex----------------------------
> // Output a 16 bit number in unsigned hexadecimal format
> // Input: 16-bit number to be transferred, unsigned int port
> // Output: none
> // Variable format 1 to 4 digits with no space before or after
> void SCI_OutUHex(unsigned short number,unsigned int port){
> // This function uses recursion to convert the number of
> // unspecified length as an ASCII string
> if(number>=0x10) {
> SCI_OutUHex(number/0x10,port);
> SCI_OutUHex(number%0x10,port);
> }
> else if(number<0xA){
> SCI_OutChar(number+'0',port);
> }
> else{
> SCI_OutChar((number-0x0A)+'A',port);
> }
> }
>
> //------------------------SCI_InString------------------------
> // This function accepts ASCII characters from the serial port
> // and adds them to a string until a carriage return is inputted
> // or until max length of the string is reached.
> // It echoes each character as it is inputted.
> // If a backspace is inputted, the string is modified
> // and the backspace is echoed
> // InString terminates the string with a null character
> // -- Modified by Agustinus Darmawan + Mingjie Qiu --
> void SCI_InString(char *string,unsigned short max,unsigned int port)
> {
> int length=0;
> char character;
> character = SCI_InChar(port);
> while(character!=CR)
> {
> if(character==BS)
> {
> if(length)
> {
> string--;
> length--;
> SCI_OutChar(BS,port);
> }
> }
> else if(length > {
> *string++=character;
> length++;
> SCI_OutChar(character,port);
> }
> character = SCI_InChar(port);
> }
> *string = 0;
> }
>
> ------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - Bill Auerbach - Oct 27 1:02:08 2009

> Edward Karpicz writes on 12:51 AM 10/27/2009
>Probably malloc didn't succeed
>
>char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char
>
>BTW comment is wrong, should be make room for 5 pointers to char

Both points are good.

Furthermore, for this series of processors or smaller and generally
in embedded systems, avoid malloc and free. These smaller processors
are just not that good at supporting dynamic memory. For a Freescale
PowerPC with 100's of MB of memory - fine, dynamic memory using
malloc and free can be used. But you must always consider that
memory can fragment and requests for memory can fail over long runs
of the program (malloc returns NULL on error).

I'm not looking for a big debate on malloc/free in an embedded
system. On a system with less than 32MB of RAM, I just don't do it - ever.

Bill
>Edward
>
>----- Original Message -----
>From: <z...@gmail.com>
>To: <6...@yahoogroups.com>
>Sent: Monday, October 26, 2009 10:26 PM
>Subject: [68HC12] Dragon Board 12 Serial Communication C code Help
>
> > Hello all, I am hoping someone has some incite as to what I am doing wrong
> > here, I figure it is a small problem but I am out of ideas. This is just a
> > test to figure out how to pass char * through methods. The code should
> > print Hello World to the serial port which it does, then print tes
> > repeatedly, which it does not, rather the output is as follows:
> >
> > Hello World"""""""""""""""""""""""""""""""""""""""""""""""""""""""
> > """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
> >
> > Here is the code, also below is the sci.c and sci.h that do the actually
> > serial communication.
> >
> > Thank You in advanced !
> >
> > Zach Long
> >
> > MAIN:
> >
> > #include "sci.h"
> >
> > int main(void);
> > void encode(char *out);
> >
> > int main(void)
> > {
> > char* head = "Hello World"; // declare first print statement
> > char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char
> >
> > SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD
> > SCI_OutStatus(1); // Is it clear to send (buffer empty)
> > SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!)
> >
> > while(1)
> > {
> > if(SCI_OutStatus(0))// Is it clear to send (buffer empty)
> > {
> > encode(outData);//,out.throt,out.heading); // build output
> > SCI_OutString(outData,0); // print out put to serial port
> > }
> > }
> > return 0;
> > }
> >
> > void encode(char *out) // take in pointer and fill with chars
> > {
> > out[0] = 't';
> > out[1] = 'e';
> > out[2] = 's';
> > out[3] = 0;
> > }
> >
> > SCI include:
> >
> > // filename ******************* SCI.H **************************
> > // Jonathan W. Valvano 1/29/04
> >
> > // This example accompanies the books
> > // "Embedded Microcomputer Systems: Real Time Interfacing",
> > // Brooks-Cole, copyright (c) 2000,
> > // "Introduction to Embedded Microcomputer Systems:
> > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002
> >
> > // Copyright 2004 by Jonathan W. Valvano,
> v...@mail.utexas.edu
> > // You may use, edit, run or distribute this file
> > // as long as the above copyright notice remains
> > // Modified by EE345L students Charlie Gough && Matt Hawk
> > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
> > // Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600
> > BAUD, use of both serial ports enabled)
> >
> > //How To
> > /*
> > Each method has an unsigned int port parameter, this specifices the
> > serial port
> > the method will act on. Dragon Board 12: Serial port under LCD (top) =
> > 0, Serial port near power plug (bottom) = 1
> > */
> >
> > // standard ASCII symbols
> > #define CR 0x0D
> > #define LF 0x0A
> > #define BS 0x08
> > #define ESC 0x1B
> > #define SP 0x20
> > #define DEL 0x7F
> >
> > //-------------------------SCI_Init------------------------
> > //-------------------------SCI_Init------------------------
> > // Initialize Serial port SCI
> > // Input: baudRate is tha baud rate in bits/sec
> > // Output: none
> > // SCIBDL = 24000000/(16 x BR)
> > // baudRate = 2400 bits/sec SCIBDL=625
> > // baudRate = 4800 bits/sec SCIBDL=313
> > // baudRate = 9600 bits/sec SCIBDL=156
> > // baudRate = 19200 bits/sec SCIBDL=78
> > // assumes a module clock frequency of 4 MHz
> > // sets baudRate to 9600
> > void SCI_Init(unsigned short baudRate,unsigned int port);
> >
> > //-------------------------SCI_InStatus--------------------------
> > // Checks if new input is ready, TRUE if new input is ready
> > // Input: unsigned int port
> > // Output: TRUE if a call to InChar will return right away with data
> > // FALSE if a call to InChar will wait for input
> > char SCI_InStatus(unsigned int port);
> >
> > //-------------------------SCI_InChar------------------------
> > // Wait for new serial port input, busy-waiting synchronization
> > // Input: unsigned int port
> > // Output: ASCII code for key typed
> > char SCI_InChar(unsigned int port);
> >
> > void SCI_InString(char* string,unsigned short max,unsigned int port); //
> > Reads in a String of max length
> >
> > //----------------------SCI_InUDec-------------------------------
> > // InUDec accepts ASCII input in unsigned decimal format
> > // and converts to a 16 bit unsigned number
> > // valid range is 0 to 65535
> > // Input: unsigned int port
> > // Output: 16-bit unsigned number
> > // If you enter a number above 65535, it will truncate without an error
> > // Backspace will remove last digit typed
> > unsigned short SCI_InUDec(unsigned int port);
> >
> > //---------------------SCI_InUHex----------------------------------------
> > // Accepts ASCII input in unsigned hexadecimal (base 16) format
> > // Input: unsigned int port
> > // Output: 16-bit unsigned number
> > // No '$' or '0x' need be entered, just the 1 to 4 hex digits
> > // It will convert lower case a-f to uppercase A-F
> > // and converts to a 16 bit unsigned number
> > // value range is 0 to FFFF
> > // If you enter a number above FFFF, it will truncate without an error
> > // Backspace will remove last digit typed
> > unsigned short SCI_InUHex(unsigned int port);
> >
> > //-----------------------SCI_OutStatus----------------------------
> > // Checks if output data buffer is empty, TRUE if empty
> > // Input: unsigned int port
> > // Output: TRUE if a call to OutChar will output and return right away
> > // FALSE if a call to OutChar will wait for output to be ready
> > char SCI_OutStatus(unsigned int port);
> >
> > //-------------------------SCI_OutChar------------------------
> > // Wait for buffer to be empty, output 8-bit to serial port
> > // busy-waiting synchronization
> > // Input: 8-bit data to be transferred, unsigned int port
> > // Output: none
> > void SCI_OutChar(char data,unsigned int port);
> >
> > //-----------------------SCI_OutUDec-----------------------
> > // Output a 16-bit number in unsigned decimal format
> > // Input: 16-bit number to be transferred, unsigned int port
> > // Output: none
> > // Variable format 1-5 digits with no space before or after
> > void SCI_OutUDec(unsigned short,unsigned int port);
> >
> > //-------------------------SCI_OutString------------------------
> > // Output String (NULL termination), busy-waiting synchronization
> > // Input: pointer to a NULL-terminated string to be transferred, unsigned
> > int port
> > // Output: none
> > void SCI_OutString(char *pt,unsigned int port);
> >
> > //--------------------------SCI_OutUHex----------------------------
> > // Output a 16 bit number in unsigned hexadecimal format
> > // Input: 16-bit number to be transferred, unsigned int port
> > // Output: none
> > // Variable format 1 to 4 digits with no space before or after
> > void SCI_OutUHex(unsigned short,unsigned int port);
> >
> >
> >
> > // filename *************** SCI.C ******************************
> > // Simple I/O routines to 9S12C32 serial port
> > // Jonathan W. Valvano 1/29/04
> >
> > // This example accompanies the books
> > // "Embedded Microcomputer Systems: Real Time Interfacing",
> > // Brooks-Cole, copyright (c) 2000,
> > // "Introduction to Embedded Microcomputer Systems:
> > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002
> >
> > // Copyright 2004 by Jonathan W. Valvano,
> v...@mail.utexas.edu
> > // You may use, edit, run or distribute this file
> > // as long as the above copyright notice remains
> > // Modified by EE345L students Charlie Gough && Matt Hawk
> > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu
> > // Modified by Steven Lamb April 28, 2004 (minor changes for g++)
> > // Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use
> > of both serial ports enabled)
> >
> >
> > //How To
> > /*
> >
> > */
> >
> > #include "hcs12.h" // io register map
> > #include "SCI.h"
> > #define RDRF 0x20 // Receive Data Register Full Bit
> > #define TDRE 0x80 // Transmit Data Register Empty Bit
> >
> >
> > //-------------------------SCI_Init------------------------
> > // Initialize Serial port SCI
> > // Input: baudRate is tha baud rate in bits/sec
> > // Output: none
> > // SCIBDL = 24000000/(16 x BR)
> > // baudRate = 2400 bits/sec SCIBDL=625
> > // baudRate = 4800 bits/sec SCIBDL=313
> > // baudRate = 9600 bits/sec SCIBDL=156
> > // baudRate = 19200 bits/sec SCIBDL=78
> > // assumes a module clock frequency of 4 MHz
> > // sets baudRate to 9600
> > void SCI_Init(unsigned short baudRate, unsigned int port)
> > {
> > switch(port)
> > {
> > case 0:
> > {
> > SCI0BDH = 0;
> > switch(baudRate)
> > {
> > case 2400: SCI0BDL=625; break;
> > case 4800: SCI0BDL=313; break;
> > case 9600: SCI0BDL=156; break;
> > case 19200: SCI0BDL=78; break;
> > default: SCI0BDL = 156 ; // 9600
> > }
> > break;
> >
> > SCI0CR1 = 0;
> > /* bit value meaning
> > 7 0 LOOPS, no looping, normal
> > 6 0 WOMS, normal high/low outputs
> > 5 0 RSRC, not appliable with LOOPS=0
> > 4 0 M, 1 start, 8 data, 1 stop
> > 3 0 WAKE, wake by idle (not applicable)
> > 2 0 ILT, short idle time (not applicable)
> > 1 0 PE, no parity
> > 0 0 PT, parity type (not applicable with PE=0)
> > */
> >
> > SCI0CR2 = 0x0C;
> > /* bit value meaning
> > 7 0 TIE, no transmit interrupts on TDRE
> > 6 0 TCIE, no transmit interrupts on TC
> > 5 0 RIE, no receive interrupts on RDRF
> > 4 0 ILIE, no interrupts on idle
> > 3 1 TE, enable transmitter
> > 2 1 RE, enable receiver
> > 1 0 RWU, no receiver wakeup
> > 0 0 SBK, no send break
> > */
> > break;
> > }
> > case 1:
> > {
> > SCI1BDH = 0;
> > switch(baudRate)
> > {
> > case 2400: SCI1BDL=625; break;
> > case 4800: SCI1BDL=313; break;
> > case 9600: SCI1BDL=156; break;
> > case 19200: SCI1BDL=78; break;
> > default: SCI1BDL = 156 ; // 9600
> > }
> > break;
> >
> > SCI1CR1 = 0;
> > /* bit value meaning
> > 7 0 LOOPS, no looping, normal
> > 6 0 WOMS, normal high/low outputs
> > 5 0 RSRC, not appliable with LOOPS=0
> > 4 0 M, 1 start, 8 data, 1 stop
> > 3 0 WAKE, wake by idle (not applicable)
> > 2 0 ILT, short idle time (not applicable)
> > 1 0 PE, no parity
> > 0 0 PT, parity type (not applicable with PE=0)
> > */
> >
> > SCI1CR2 = 0x0C;
> > /* bit value meaning
> > 7 0 TIE, no transmit interrupts on TDRE
> > 6 0 TCIE, no transmit interrupts on TC
> > 5 0 RIE, no receive interrupts on RDRF
> > 4 0 ILIE, no interrupts on idle
> > 3 1 TE, enable transmitter
> > 2 1 RE, enable receiver
> > 1 0 RWU, no receiver wakeup
> > 0 0 SBK, no send break
> > */
> > break;
> > }
> > }
> > }
> >
> >
> > //-------------------------SCI_InChar------------------------
> > // Wait for new serial port input, busy-waiting synchronization
> > // Input: int port
> > // Output: ASCII code for key typed
> > char SCI_InChar(unsigned int port)
> > {
> > switch(port)
> > {
> > case 0:
> > while((SCI0SR1 & RDRF) == 0){};
> > return(SCI0DRL);
> > break;
> > case 1:
> > while((SCI1SR1 & RDRF) == 0){};
> > return(SCI1DRL);
> > break;
> > }
> > }
> >
> > //-------------------------SCI_OutChar------------------------
> > // Wait for buffer to be empty, output 8-bit to serial port
> > // busy-waiting synchronization
> > // Input: 8-bit data to be transferred
> > // Output: none
> > void SCI_OutChar(char data,unsigned int port)
> > {
> > switch(port)
> > {
> > case 0:
> > while((SCI0SR1 & TDRE) == 0){};
> > SCI0DRL = data;
> > break;
> > case 1:
> > while((SCI1SR1 & TDRE) == 0){};
> > SCI1DRL = data;
> > break;
> > }
> > }
> >
> > //-------------------------SCI_InStatus--------------------------
> > // Checks if new input is ready, TRUE if new input is ready
> > // Input: unsigned int port
> > // Output: TRUE if a call to InChar will return right away with data
> > // FALSE if a call to InChar will wait for input
> > char SCI_InStatus(unsigned int port)
> > {
> > switch(port)
> > {
> > case 0:
> > return(SCI0SR1 & RDRF);break;
> > case 1:
> > return(SCI1SR1 & RDRF);break;
> > }
> > }
> > //-----------------------SCI_OutStatus----------------------------
> > // Checks if output data buffer is empty, TRUE if empty
> > // Input: unsigned int port
> > // Output: TRUE if a call to OutChar will output and return right away
> > // FALSE if a call to OutChar will wait for output to be ready
> > char SCI_OutStatus(unsigned int port)
> > {
> > switch(port)
> > {
> > case 0:
> > return(SCI0SR1 & TDRE);
> > break;
> > case 1:
> > return(SCI1SR1 & TDRE);
> > break;
> > }
> > }
> >
> >
> > //-------------------------SCI_OutString------------------------
> > // Output String (NULL termination), busy-waiting synchronization
> > // Input: pointer to a NULL-terminated string to be transferred, unsigned
> > int port
> > // Output: none
> > void SCI_OutString(char *pt,unsigned int port)
> > {
> > while(*pt){
> > SCI_OutChar(*pt,port);
> > pt++;
> > }
> > }
> >
> > //----------------------SCI_InUDec-------------------------------
> > // InUDec accepts ASCII input in unsigned decimal format
> > // and converts to a 16 bit unsigned number
> > // valid range is 0 to 65535
> > // Input: unsigned int port
> > // Output: 16-bit unsigned number
> > // If you enter a number above 65535, it will truncate without an error
> > // Backspace will remove last digit typed
> > unsigned short SCI_InUDec(unsigned int port)
> > {
> > unsigned short number=0, length=0;
> > char character;
> > character = SCI_InChar(port);
> > while(character!=CR) // accepts until carriage return input
> > {
> > // The next line checks that the input is a digit, 0-9.
> > // If the character is not 0-9, it is ignored and not echoed
> > if((character>='0') && (character<='9'))
> > {
> > number = 10*number+(character-'0'); // this line overflows if
> > above 65535
> > length++;
> > SCI_OutChar(character,port);
> > }
> > // If the input is a backspace, then the return number is
> > // changed and a backspace is outputted to the screen
> > else if((character==BS) && length)
> > {
> > number /= 10;
> > length--;
> > SCI_OutChar(character,port);
> > }
> > character = SCI_InChar(port);
> > }
> > return number;
> > }
> >
> >
> > //-----------------------SCI_OutUDec-----------------------
> > // Output a 16-bit number in unsigned decimal format
> > // Input: 16-bit number to be transferred, unsigned int port
> > // Output: none
> > // Variable format 1-5 digits with no space before or after
> > void SCI_OutUDec(unsigned short n,unsigned int port)
> > {
> > // This function uses recursion to convert decimal number
> > // of unspecified length as an ASCII string
> > if(n >= 10){
> > SCI_OutUDec(n/10,port);
> > n = n%10;
> > }
> > SCI_OutChar(n+'0',port); /* n is between 0 and 9 */
> > }
> >
> >
> >
> > //---------------------SCI_InUHex----------------------------------------
> > // Accepts ASCII input in unsigned hexadecimal (base 16) format
> > // Input: unsigned int port
> > // Output: 16-bit unsigned number
> > // No '$' or '0x' need be entered, just the 1 to 4 hex digits
> > // It will convert lower case a-f to uppercase A-F
> > // and converts to a 16 bit unsigned number
> > // value range is 0 to FFFF
> > // If you enter a number above FFFF, it will truncate without an error
> > // Backspace will remove last digit typed
> > unsigned short SCI_InUHex(unsigned int port){
> > unsigned short number=0, digit, length=0;
> > char character;
> > character = SCI_InChar(port);
> > while(character!=CR){
> > digit = 0x10; // assume bad
> > if((character>='0') && (character<='9')){
> > digit = character-'0';
> > }
> > else if((character>='A') && (character<='F')){
> > digit = (character-'A')+0xA;
> > }
> > else if((character>='a') && (character<='f')){
> > digit = (character-'a')+0xA;
> > }
> > // If the character is not 0-9 or A-F, it is ignored and not echoed
> > if(digit<=0xF ){
> > number = number*0x10+digit;
> > length++;
> > SCI_OutChar(character,port);
> > }
> > // Backspace outputted and return value changed if a backspace is inputted
> > else if(character==BS && length){
> > number /=0x10;
> > length--;
> > SCI_OutChar(character,port);
> > }
> > character = SCI_InChar(port);
> > }
> > return number;
> > }
> >
> > //--------------------------SCI_OutUHex----------------------------
> > // Output a 16 bit number in unsigned hexadecimal format
> > // Input: 16-bit number to be transferred, unsigned int port
> > // Output: none
> > // Variable format 1 to 4 digits with no space before or after
> > void SCI_OutUHex(unsigned short number,unsigned int port){
> > // This function uses recursion to convert the number of
> > // unspecified length as an ASCII string
> > if(number>=0x10) {
> > SCI_OutUHex(number/0x10,port);
> > SCI_OutUHex(number%0x10,port);
> > }
> > else if(number<0xA){
> > SCI_OutChar(number+'0',port);
> > }
> > else{
> > SCI_OutChar((number-0x0A)+'A',port);
> > }
> > }
> >
> > //------------------------SCI_InString------------------------
> > // This function accepts ASCII characters from the serial port
> > // and adds them to a string until a carriage return is inputted
> > // or until max length of the string is reached.
> > // It echoes each character as it is inputted.
> > // If a backspace is inputted, the string is modified
> > // and the backspace is echoed
> > // InString terminates the string with a null character
> > // -- Modified by Agustinus Darmawan + Mingjie Qiu --
> > void SCI_InString(char *string,unsigned short max,unsigned int port)
> > {
> > int length=0;
> > char character;
> > character = SCI_InChar(port);
> > while(character!=CR)
> > {
> > if(character==BS)
> > {
> > if(length)
> > {
> > string--;
> > length--;
> > SCI_OutChar(BS,port);
> > }
> > }
> > else if(length > > {
> > *string++=character;
> > length++;
> > SCI_OutChar(character,port);
> > }
> > character = SCI_InChar(port);
> > }
> > *string = 0;
> > }
> >
> >
> >
> >
> >
> > ------------------------------------
> >
> >



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - Andrei Chichak - Oct 27 2:27:30 2009

I agree that malloc failed and it is passing back 0 to indicate that
it failed, and you are using that as an address of your string.

Please have some empathy for the programmer that has to figure out
your bugs. Check your return codes, don't use malloc, calloc, realloc,
global variables, GOTOs, or "magic numbers".

A
On 2009-October-26, at 11:01 PM, Bill Auerbach wrote:
>
> Furthermore, for this series of processors or smaller and generally
> in embedded systems, avoid malloc and free.
>

[Non-text portions of this message have been removed]

------------------------------------

______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.


(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - zach...@gmail.com - Oct 27 21:39:13 2009

Thanks everyone, your comments on not using malloc make sense for this system, however I am still left with the issue of incorrect output, and the thought of how that pointer works if it is never assigned to memory. Not to get side tracked, if anyone has any working examples of printing variable data to the serial port I would be very interested in seeing it, since this is the goal of this series of post.
Thank You,

Zach
------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - Bill_CT - Oct 27 22:40:56 2009

Zach,

The code for the serial port looks OK, although for production code it would benefit from a code review.

SCI_OutStatus(1); // Is it clear to send (buffer empty)

This returns the status, so as is in main does nothing. Since SCI_OutString checks the SCI status for each character, testing the status before the call isn't needed anyway.

The following might work (I don't have a running system or I would run it).

Bill
-------------
int main(void)
{
char* head = "Hello World"; // declare first print statement
char outData[5]; // make room for 5 char

SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD
SCI_OutStatus(1); // Is it clear to send (buffer empty)
SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!)

while(1)
{
if(SCI_OutStatus(0))// Is it clear to send (buffer empty)
{
encode(outData);//,out.throt,out.heading); // build output
SCI_OutString(outData,0); // print out put to serial port
}
}
return 0;
}

void encode(char *out) // take in pointer and fill with chars
{
out[0] = 't';
out[1] = 'e';
out[2] = 's';
out[3] = 0;
}
--- In 6...@yahoogroups.com, zach.r.long@... wrote:
>
> Thanks everyone, your comments on not using malloc make sense for this system, however I am still left with the issue of incorrect output, and the thought of how that pointer works if it is never assigned to memory. Not to get side tracked, if anyone has any working examples of printing variable data to the serial port I would be very interested in seeing it, since this is the goal of this series of post.
> Thank You,
>
> Zach
>

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Re: Dragon Board 12 Serial Communication C code Help - Andrei Chichak - Oct 28 2:21:28 2009

Okay, let's take a look at the output and the evidence and make some
wild ass guesses.

You can assume that SCI_OutString is okay since 1) the "Hello World"
comes out okay and 2) it is what is known as gospel code - written by
a god like being and written in a book.

Next, in your message you say "then print tes repeatedly". Well, it
isn't printing tes (plural of T??) it is printing double quotes.
Nowhere in your code do you have a buffer that should be holding a ".
So we can assume that either encode() isn't working properly (but by
inspection it is pretty simple), or when you call SCI_OutString, you
are using a garbage pointer and it is printing random stuff.

In the definition of encode - either use pointers or arrays, don't
intermix. Use void encode( char out[]) instead. What you have would
probably cause all kinds of damage.
Now, the character " has the hex value 0x22, so what you are printing
looks like 22222222222222222... in hex, with no 0x00 to terminate the
string, so it's going to print a whole bunch of it. It is quite hard
to determine what you are printing since you are in an infinite loop.
The data could be 0x2200, which would print out a single ", but since
it is in an infinite loop you would get """"""""""""""""""""""""""".

Running your code through lint showed that if malloc failed you would
have outData getting set to NULL. This would be a pointer to location
0. Encode would try and alter locations 0, 1, 2 and 3. Then you print
the string at location 0. The zero page of an HC12 is internal
registers. So you would set PORTA to 0x74, PORTB to 0x65, DDRA to
0x73, DDRB to 0x00, then print them out as a string.

If you are running some sort of a bootloader/monitor/debugger it is
possible to move the registers and possibly put FLASH down in the zero
page, or uninitialized RAM. It's really hard to predict what is going
to get printed.

Either way, you are printing a location that IS a long string of hex
0x22. We can see that from the output.

First, alter your code to have:

No infinite loop until you get a bit of control.

Fix encode as above.

char outData[5];
Then, use SCI_OutChar(outData[0]); and make sure that you are getting
a 't'. This would make sure that encode is working properly.

Fix the malloc call so that the syntax is expressing what you actually
want and check the return code. Use SCI_OutString to print an error
message if malloc returns NULL.

If you really want to use malloc, use SCI_OutUHex((int)outData) and
take a look at where outData is pointing. I'm pretty sure that you
will find a whole bunch of 0x22 at that location.

From the 10 commandments: Thou shalt run lint frequently and study
its pronouncements with care, for verily its perception and judgement
oft exceed thine.
From the MISRA guidelines: Don't use pointers.

Andrei
---------------------
Andrei Chichak

Systems Developer
CBF Systems Inc.
4-038 NINT Innovation Centre
11421 Saskatchewan Drive
Edmonton, Alberta
Canada
T6G 2M9

Phone: 780-628-2072
Skype: andrei.chichak

[Non-text portions of this message have been removed]

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - Robert - Oct 28 10:11:08 2009

As stated by others it is folly to use malloc/free in simple embedded systems. The best solution is to implement asynchronous static ring buffers for rx/tx with timeout error reporting (see http://www.seattlerobotics.org/encoder/200009/sciint11.c for an asynch example without timeouts). In the case where the output is fixed I wouldn't even bother with a buffer.

#ifndef bit
#define bit(x) (1 << (x))
#endif

void put_char(char c) {
while((SCI0SR1 & bit(7)) == 0);
SCI0DRL = c;
}

void put_s(char* s) {
// Assumes char pointer is a zero terminated array (string)
while(*s)
put_char(*s++);
}

const char *message = "Hello World";
const char *test_str = "tes0";

void main(void) {
sci_init(); // usual sci setup for baudrate, etc.
put_s(message);
while(1) {
put_s(test_str);
}
}

If the output is variable, the addition of the something like the following can be useful. The obvious danger of using this function is the ease of overflowing the buffer. Beware also that compiler implementations of this are typically not re-entrant so don't call it from inside an ISR or thread.

#include

void myPrintf(char *format, ...) {
char buffer[BUF_SIZE];
va_list stArgList;

va_start(stArgList, format);
vsprintf(buffer, format, stArgList);
va_end(stArgList);
put_s(buffer);
}

-rob

>
> #include "sci.h"
>
> int main(void);
> void encode(char *out);
>
> int main(void)
> {
> char* head = "Hello World"; // declare first print statement
> char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char
>
> SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD
> SCI_OutStatus(1); // Is it clear to send (buffer empty)
> SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!)
>
> while(1)
> {
> if(SCI_OutStatus(0))// Is it clear to send (buffer empty)
> {
> encode(outData);//,out.throt,out.heading); // build output
> SCI_OutString(outData,0); // print out put to serial port
> }
> }
> return 0;
> }
>
> void encode(char *out) // take in pointer and fill with chars
> {
> out[0] = 't';
> out[1] = 'e';
> out[2] = 's';
> out[3] = 0;
> }

------------------------------------

______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.


(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Re: Dragon Board 12 Serial Communication C code Help - Bill Auerbach - Oct 29 21:54:55 2009

> Andrei Chichak writes on 02:20 AM 10/28/2009
>In the definition of encode - either use pointers or arrays, don't
>intermix. Use void encode( char out[]) instead. What you have would
>probably cause all kinds of damage.

There is no harm to use pointers and arrays and no damage results
from doing so. They are equivalent - the only time a problem will
occur is when a pointer and array are used in different modules (one
public and the other externed).
Bill

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Re: Dragon Board 12 Serial Communication C code Help - Andrei Chichak - Oct 29 22:24:52 2009


On 2009-October-28, at 11:06 PM, Bill Auerbach wrote:
>> > Andrei Chichak writes on 02:20 AM 10/28/2009
>> >In the definition of encode - either use pointers or arrays, don't
>> >intermix. Use void encode( char out[]) instead. What you have would
>> >probably cause all kinds of damage.
>>
>> There is no harm to use pointers and arrays and no damage results
>> from doing so. They are equivalent - the only time a problem will
>> occur is when a pointer and array are used in different modules (one
>> public and the other externed).
>>
>> Bill
>
> Remember, the program will only be read twice after you write it,
> once by the compiler (and it doesn't care what you do), and the poor
> sod that has to maintain it.

[Non-text portions of this message have been removed]

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Dragon Board 12 Serial Communication C code Help - Bill_CT - Oct 31 10:54:57 2009



--- In 6...@yahoogroups.com, Andrei Chichak wrote:
> On 2009-October-28, at 11:06 PM, Bill Auerbach wrote:
> >> > Andrei Chichak writes on 02:20 AM 10/28/2009
> >> >In the definition of encode - either use pointers or arrays, don't
> >> >intermix. Use void encode( char out[]) instead. What you have would
> >> >probably cause all kinds of damage.

You say "probably cause all kinds of damage". Before anyone here thinks that's a really bad thing and it means they are doing something wrong, perhaps you should back this statement with something concrete. Show us a case that causes "all kinds of damage". If you can't, please don't put your gloom and doom programming rules out on a public forum where beginners may be trying to learn correct programming practices.

> >> There is no harm to use pointers and arrays and no damage results
> >> from doing so. They are equivalent - the only time a problem will
> >> occur is when a pointer and array are used in different modules (one
> >> public and the other externed).
> >>
> >> Bill
> >
>> Remember, the program will only be read twice after you write it,
>> once by the compiler (and it doesn't care what you do), and the poor
>> sod that has to maintain it.

It's a much larger concern and problem if the maintainer doesn't know the fundamental properties and semantics of the language.

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Re: Dragon Board 12 Serial Communication C code Help - Tom Almy - Oct 31 11:58:04 2009


On Oct 31, 2009, at 7:54 AM, Bill_CT wrote:

> --- In 6...@yahoogroups.com, Andrei Chichak wrote:
>> On 2009-October-28, at 11:06 PM, Bill Auerbach wrote:
>>>>> Andrei Chichak writes on 02:20 AM 10/28/2009
>>>>> In the definition of encode - either use pointers or arrays, don't
>>>>> intermix. Use void encode( char out[]) instead. What you have
>>>>> would
>>>>> probably cause all kinds of damage.
>
> You say "probably cause all kinds of damage". Before anyone here
> thinks that's a really bad thing and it means they are doing
> something wrong, perhaps you should back this statement with
> something concrete. Show us a case that causes "all kinds of
> damage". If you can't, please don't put your gloom and doom
> programming rules out on a public forum where beginners may be
> trying to learn correct programming practices.

This struck me as particularly strange since I've been mixing pointers
and arrays since 1980 (when I first used C) and have never caused any
kind of damage! In fact you really need to mix the two to get maximum
leverage from the language.

1. You have to declare arrays to allocate memory since I think most of
us can agree that malloc has no
business in embedded programming of small microcontrollers.
2. It is generally more efficient to walk through an array using
pointers rather than indexing.
3. Array and pointer parameters are basically identical since the
array is passed by reference and the pointer is passed by value. They
can be used interchangeably.
4. The comment "the only time a problem will occur is when a pointer
and array are used in different modules (one public and the other
externed)" isn't an issue if using header files with extern
declarations for all global variables is practiced. This will catch
the definition being different than the declaration.

Tom Almy
Tualatin, Oregon USA
Internet: t...@almy.us
Website: almy.us

------------------------------------

______________________________
Stellaris® MCU Family: New Parts, New Package, New Price.


(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )

Re: Re: Dragon Board 12 Serial Communication C code Help - Bill Auerbach - Nov 1 11:52:24 2009

> Tom Almy writes on 10:57 AM 10/31/2009
>This struck me as particularly strange since I've been mixing pointers
>and arrays since 1980 (when I first used C) and have never caused any
>kind of damage! In fact you really need to mix the two to get maximum
>leverage from the language.

Technically "Hello World" mixes an array used with printf which takes
a pointer.

>1. You have to declare arrays to allocate memory since I think most of
>us can agree that malloc has no
>business in embedded programming of small microcontrollers.

Agree.

>2. It is generally more efficient to walk through an array using
>pointers rather than indexing.

Yes. I might not be wrong to say it's always more efficient.

>3. Array and pointer parameters are basically identical since the
>array is passed by reference and the pointer is passed by value. They
>can be used interchangeably.

Yes. The one place that can burn you because of this is sizeof used
on an argument to a function with an array type:

void function(char buffer[32])
{
int i = sizeof buffer; // This is NOT 32 but sizeof (char *)
}

However, this isn't going to cause "damage" because this error would
fall out quickly in testing.

>4. The comment "the only time a problem will occur is when a pointer
>and array are used in different modules (one public and the other
>externed)" isn't an issue if using header files with extern
>declarations for all global variables is practiced. This will catch
>the definition being different than the declaration.

I agree. It shouldn't be an issue, but since it can be done, it is a
problem when it is. I've seen a lot of programmer's code over the
years and there's a lot of "quick extern" declarations that are
included in the C file and not a header file. It's not a good
practice but it's still pretty common.
Bill

------------------------------------



(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )