timfv
New Member
Posts: 2
|
Post by timfv on Nov 9, 2011 21:53:32 GMT 1
I am attempting to access a serial port (for reading and writing) in a BaCon program under Linux. However, the documentation does not tell me how to accomplish this. Is serial port access supported under BaCon? If not, are there any workarounds (shared libraries, etc) available?
|
|
|
Post by Pjot on Nov 10, 2011 13:36:54 GMT 1
Hi timfv, You might get this running with the "Columbo Simple Serial Library". cssl.sourceforge.netRegards Peter
|
|
|
Post by Pjot on Nov 10, 2011 15:07:47 GMT 1
Because I have some time left I hacked my way through this. First you need to compile the source file 'cssl.c' from the libcssl package as follows:
Then take a look at the following code on how to use it. Make sure you use the correct device filename for your serial port. I use "/dev/ttyS0".
' Library name lib$ = "./libcssl.so"
' LIB functions IMPORT "cssl_geterror(void)" FROM lib$ TYPE int IMPORT "cssl_geterrormsg(void)" FROM lib$ TYPE char* IMPORT "cssl_start(void)" FROM lib$ TYPE void IMPORT "cssl_stop(void)" FROM lib$ TYPE void IMPORT "cssl_open(char*,void*,int,int,int,int,int)" FROM lib$ TYPE long IMPORT "cssl_close(long)" FROM lib$ TYPE void IMPORT "cssl_setup(long,int,int,int,int)" FROM lib$ TYPE void IMPORT "cssl_setflowcontrol(long,int,int)" FROM lib$ TYPE void IMPORT "cssl_putchar(long,char)" FROM lib$ TYPE void IMPORT "cssl_putstring(long,char*)" FROM lib$ TYPE void IMPORT "cssl_putdata(long,void*,int)" FROM lib$ TYPE void IMPORT "cssl_drain(long)" FROM lib$ TYPE void IMPORT "cssl_settimeout(long,int)" FROM lib$ TYPE void IMPORT "cssl_getchar(long)" FROM lib$ TYPE int IMPORT "cssl_getdata(long,void*,int)" FROM lib$ TYPE int
' Enumeration CONST CSSL_OK = 0 CONST CSSL_ERROR_NOSIGNAL = 1 CONST CSSL_ERROR_NOTSTARTED = 2 CONST CSSL_ERROR_NULLPOINTER = 3 CONST CSSL_ERROR_OOPS = 4 CONST CSSL_ERROR_MEMORY = 5 CONST CSSL_ERROR_OPEN = 6
' Callback function SUB callback PRINT "Data arrived!" END SUB
' Start library cssl_start
' Open serial port serial = cssl_open("/dev/ttyS0", callback, 1, 9600, 8, 0, 1)
' Send data cssl_putstring(serial, "Hello world")
' Close port cssl_close(serial)
' Stop library cssl_stop
Hope this helps, Peter
|
|
timfv
New Member
Posts: 2
|
Post by timfv on Nov 11, 2011 6:02:17 GMT 1
Thank you for your help. Unfortunately, this isn't fully functional. It seems to transmit data properly, but not receive, and the callback function doesn't appear to work at all. Do you have any further ideas on how to use the callback function (or configure the library to use blocking mode) under BaCon?
|
|
|
Post by Pjot on Nov 11, 2011 9:04:52 GMT 1
Well, I am not a specialist with serial programming, nor with this library. Did you check the README file in the package where all functions are explained? You may need to fiddle around with 'cssl_drain()' for example.
There is a testprogram called "test.c" which appears to test the input from a serial keyboard. Below the conversion to BaCon FWIIW.
' Library name lib$ = "./libcssl.so"
' LIB functions IMPORT "cssl_geterror(void)" FROM lib$ TYPE int IMPORT "cssl_geterrormsg(void)" FROM lib$ TYPE char* ALIAS cssl_geterrormsg$ IMPORT "cssl_start(void)" FROM lib$ TYPE void IMPORT "cssl_stop(void)" FROM lib$ TYPE void IMPORT "cssl_open(char*,void*,int,int,int,int,int)" FROM lib$ TYPE long IMPORT "cssl_close(long)" FROM lib$ TYPE void IMPORT "cssl_setup(long,int,int,int,int)" FROM lib$ TYPE void IMPORT "cssl_setflowcontrol(long,int,int)" FROM lib$ TYPE void IMPORT "cssl_putchar(long,char)" FROM lib$ TYPE void IMPORT "cssl_putstring(long,char*)" FROM lib$ TYPE void IMPORT "cssl_putdata(long,void*,int)" FROM lib$ TYPE void IMPORT "cssl_drain(long)" FROM lib$ TYPE void IMPORT "cssl_settimeout(long,int)" FROM lib$ TYPE void IMPORT "cssl_getchar(long)" FROM lib$ TYPE int IMPORT "cssl_getdata(long,void*,int)" FROM lib$ TYPE int
' Enumeration CONST CSSL_OK = 0 CONST CSSL_ERROR_NOSIGNAL = 1 CONST CSSL_ERROR_NOTSTARTED = 2 CONST CSSL_ERROR_NULLPOINTER = 3 CONST CSSL_ERROR_OOPS = 4 CONST CSSL_ERROR_MEMORY = 5 CONST CSSL_ERROR_OPEN = 6
'---------------------------------------------------------------------
DECLARE finished IMPORT pause(void) FROM "libc.so" TYPE int
' Example callback, it gets its id, buffer, and buffer length SUB callback(int id, long buf[], int length)
LOCAL i
FOR i = 0 TO length
SELECT PEEK(buf[i]) ' Ctrl-D CASE 4 finished = 1 BREAK ' Replace \r with \n CASE 13 buf[i] = 10 END SELECT
PRINT CHR$(buf[i]) NEXT
END SUB
cssl_start()
serial=cssl_open("/dev/ttyS0", callback, 0, 19200, 8, 0, 1)
IF serial = 0 THEN PRINT cssl_geterrormsg$() END -1 END IF
cssl_putstring(serial, "Type some data, ^D finishes.")
WHILE NOT(finished) pause() WEND
PRINT NL$, "^D - we exit", NL$
cssl_close(serial) cssl_stop()
Regards Peter
|
|
|
Post by volhout on Dec 22, 2011 15:12:47 GMT 1
Hi Peter, I tried your solution, but it does not work yet. Let me explain, I am using Puppy linux (WARY 5.1.4.1) and have the devx SFS installed I downloaded the CSSL package, compiled it. I am using below code. ' Library name lib$ = "./libcssl.so"
TRAP LOCAL
' LIB functions IMPORT "cssl_geterror(void)" FROM lib$ TYPE int IMPORT "cssl_geterrormsg(void)" FROM lib$ TYPE char* IMPORT "cssl_start(void)" FROM lib$ TYPE void IMPORT "cssl_stop(void)" FROM lib$ TYPE void IMPORT "cssl_open(char*,void*,int,int,int,int,int)" FROM lib$ TYPE long IMPORT "cssl_close(long)" FROM lib$ TYPE void IMPORT "cssl_setup(long,int,int,int,int)" FROM lib$ TYPE void IMPORT "cssl_setflowcontrol(long,int,int)" FROM lib$ TYPE void IMPORT "cssl_putchar(long,char)" FROM lib$ TYPE void IMPORT "cssl_putstring(long,char*)" FROM lib$ TYPE void IMPORT "cssl_putdata(long,void*,int)" FROM lib$ TYPE void IMPORT "cssl_drain(long)" FROM lib$ TYPE void IMPORT "cssl_settimeout(long,int)" FROM lib$ TYPE void IMPORT "cssl_getchar(long)" FROM lib$ TYPE int IMPORT "cssl_getdata(long,void*,int)" FROM lib$ TYPE int
' Enumeration CONST CSSL_OK = 0 CONST CSSL_ERROR_NOSIGNAL = 1 CONST CSSL_ERROR_NOTSTARTED = 2 CONST CSSL_ERROR_NULLPOINTER = 3 CONST CSSL_ERROR_OOPS = 4 CONST CSSL_ERROR_MEMORY = 5 CONST CSSL_ERROR_OPEN = 6
return$ = ""
' Callback function SUB callback(int id, long buf[], int length) LOCAL i FOR i = 0 TO length return$ = CONCAT$(return$ , CHR$(buf[i])) NEXT END SUB
' Start library cssl_start
' Open serial port serial = cssl_open("/dev/ttyS0", callback, 0, 300, 8, 0, 1)
' Send data cssl_putstring(serial, "Hello world\n")
REPEAT SLEEP 100 PRINT return$ UNTIL (INSTR(return$,"\n"))
' Close port cssl_close(serial)
' Stop library cssl_stop
I have following output when I connect the serial port input pin and output pin together as a sort of loopback function (as you can see, it almost works). To do this connect pin 2 to pin 3 on the 9 pin serial port connector I have following problems: 1/ The response is identical when I change the SLEEP 100 to SLEEP 10000 The SLEEP function does not do 10000 miliseconds. 2/ It does not work when I remove the SLEEP 100 command completely. 3/ I get only partial output when I increase the baudrate on the serial port. As if the data handling is too slow for the baudrate (below is for 9600 baud). Any thought about this Regards, Volhout
|
|
|
Post by Pjot on Dec 30, 2011 19:05:26 GMT 1
Hi volhout, Well, this is the thing when using 3rd party open source libraries: these may contain bugs. I guess best is to write a plain C program using this library to see if your objective can be achieved. (1) If it still does not work, then either you may need to write your own serial port library, or you're stuck with command line utilities like 'setserial', 'tty', 'ioctl' and friends. These can be executed with EXEC$. (2) But if such a C program works, then you can start porting it to BaCon. Regards Peter
|
|
2lss
Full Member
Posts: 140
|
Post by 2lss on Jan 19, 2012 3:50:38 GMT 1
Hi Everyone,
I don't think the problem lies in the library. I modified the test.c program (included in the cssl archive) and it works as expected. If I modify the bacon program to do the same thing, I get a strange output.
Examples (I have my microcontroller programmed to print "words lol lol" every second over ttyUSB0 @ 9600 baud)
test.c output:
words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol
Bacon output:
w o
r
d
s
l
o
l
l
o
l
It almost seems like extra blank characters are being printed. Perhaps the problem lies in CHR$?
Below are the programs
Bacon:
' Library name lib$ = "./libcssl.so"
' LIB functions IMPORT "cssl_geterror(void)" FROM lib$ TYPE int IMPORT "cssl_geterrormsg(void)" FROM lib$ TYPE char* ALIAS cssl_geterrormsg$ IMPORT "cssl_start(void)" FROM lib$ TYPE void IMPORT "cssl_stop(void)" FROM lib$ TYPE void IMPORT "cssl_open(char*,void*,int,int,int,int,int)" FROM lib$ TYPE long IMPORT "cssl_close(long)" FROM lib$ TYPE void IMPORT "cssl_setup(long,int,int,int,int)" FROM lib$ TYPE void IMPORT "cssl_setflowcontrol(long,int,int)" FROM lib$ TYPE void IMPORT "cssl_putchar(long,char)" FROM lib$ TYPE void IMPORT "cssl_putstring(long,char*)" FROM lib$ TYPE void IMPORT "cssl_putdata(long,void*,int)" FROM lib$ TYPE void IMPORT "cssl_drain(long)" FROM lib$ TYPE void IMPORT "cssl_settimeout(long,int)" FROM lib$ TYPE void IMPORT "cssl_getchar(long)" FROM lib$ TYPE int IMPORT "cssl_getdata(long,void*,int)" FROM lib$ TYPE int
DECLARE finished IMPORT pause(void) FROM "libc.so" TYPE int
' Enumeration CONST CSSL_OK = 0 CONST CSSL_ERROR_NOSIGNAL = 1 CONST CSSL_ERROR_NOTSTARTED = 2 CONST CSSL_ERROR_NULLPOINTER = 3 CONST CSSL_ERROR_OOPS = 4 CONST CSSL_ERROR_MEMORY = 5 CONST CSSL_ERROR_OPEN = 6
finished = 0
' Callback function SUB callback(int id, long buf[], int length) LOCAL i FOR i = 0 TO length PRINT CHR$(buf[i]) NEXT END SUB
' Start library cssl_start
' Open serial port serial = cssl_open("/dev/ttyUSB0", callback, 0, 9600, 8, 0, 1)
IF serial = 0 THEN PRINT cssl_geterrormsg$() END -1 END IF
WHILE NOT(finished) pause() WEND
' Send data 'cssl_putstring(serial, "Hello world")
' Close port cssl_close(serial)
' Stop library cssl_stop
test.c:
#include <stdio.h>#include <unistd.h>
#include "cssl.h"
/* if it is time to finish */ static int finished=0;
/* example callback, it gets its id, buffer, and buffer length */ static void callback(int id, uint8_t *buf, int length) { int i; // printf("Test\n"); for(i=0;i<length;i++) {
// switch (buf[i]) {
// case 0x04: /* Ctrl-D */ // finished=1; // return;
// case '\r': /* replace \r with \n */ // buf[i]='\n';
// }
putchar(buf[i]); }
fflush(stdout); }
int main() { cssl_t *serial;
cssl_start(); serial=cssl_open("/dev/ttyUSB0",callback,0, 9600,8,0,1);
if (!serial) { printf("%s\n",cssl_geterrormsg()); return -1; }
//cssl_putstring(serial,"Type some data, ^D finishes.");
while (!finished) pause();
printf("\n^D - we exit\n");
cssl_close(serial); cssl_stop();
return 0; }
|
|
|
Post by Pjot on Jan 19, 2012 10:56:40 GMT 1
The PRINT statement by default will ad a CR to any string it prints. So can you change the callback function to:
' Callback function SUB callback(int id, long buf[], int length) LOCAL i FOR i = 0 TO length PRINT CHR$(buf[i]); NEXT END SUB
...and try again?
Thanks, Peter
|
|
2lss
Full Member
Posts: 140
|
Post by 2lss on Jan 19, 2012 18:10:05 GMT 1
That seems to do it, although I'm still getting a slightly strange output from the bacon version:
words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol worlol words lol lolwords lol lol words lol lol words lol lol words lol lol words lol lol wos lol lol words lol lol words lol lol words lol lol word lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol
The test.c program does not have this problem.
|
|
|
Post by Pjot on Jan 20, 2012 16:31:36 GMT 1
The callback in the C program still is different compared to the BaCon version. This is some C code in the callback:
for(i=0;i<length;i++)
This means that the variable 'i' must be increased until but not including the variable 'length'.
However, the BaCon code says this:
FOR i = 0 TO length
But this actually includes the value of 'length' also.
Therefore, can you change the callback function once more to the following:
' Callback function SUB callback(int id, long buf[], int length) LOCAL i FOR i = 0 TO length-1 PRINT CHR$(buf[i]); NEXT END SUB
And try again?
Regards Peter
|
|
2lss
Full Member
Posts: 140
|
Post by 2lss on Jan 21, 2012 6:49:34 GMT 1
Ok. I changed the the FOR loop to 'length-1' and the output improved. However, there are still some issues with missing/wrong chatacters.
The first line is always screwed up. �!!!!!!!!!!!!!!!!!!!!rds lol lol!!!!!!!!!!!�� words lol lol words lol lol words lol lol words lol lol 'skip some lines' words lol lol words lol lol words lol words lol lol words lol lol 'repeat'
I did some investigating and decided to change 'long buf[]' to 'unsigned char buff[]'
So far it appears to be working correctly. ;D (although I'm not entirely sure why this is) I will let you know for sure after more testing.
./cssltest words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol words lol lol
|
|
|
Post by Pjot on Jan 21, 2012 21:40:17 GMT 1
Indeed the second argument in the callback is defined as a pointer to a char, but by default I always translate pointers to long. In this case however, you use unsigned char, thereby omitting any relevance for a sign...
Well found!
Regards Peter
|
|