I'm having some issues getting one (or two) of my XS-wrapped C functions to work correctly, and I've been at this for a couple of days now. Essentially, the code generates and registers a custom character for an LCD display, and then displays it. I have added the XS code for the two functions, the function declarations, a C example that works (prints the defined char), and a Perl example that doesn't (print the char). I do not know whether it's the lcdPutchar() or lcdCharDef() that's the issue, as there's no way to read the register in the LCD for the registered char.
I apologize for the length. I'm hoping by posting this (per usual), that it'll just click. Otherwise, I'm hoping someone more familiar with C/XS can perhaps spot something.
In the lcd_char_def() Perl module function, I *think* I'm generating the proper data with pack() to send to the C function (as when I printf() out the values of the array, each elem matches what I send in with a C program directly.
Here is the XS code that covers the two external C functions:
void lcdCharDef(fd, index, data) int fd int index unsigned char * data void lcdPutchar(fd, data) int fd unsigned char data
Here is the C declarations:
extern void lcdCharDef(const int fd, int index, unsigned char data [8] +); extern void lcdPutchar(const int fd, unsigned char data);
Here is the Perl module code that calls the XS:
sub lcd_char_def { shift if @_ == 4; my ($fd, $index, $data) = @_; my $unsigned_char = pack "V0C*", @$data; lcdCharDef($fd, $index, $unsigned_char); } sub lcd_put_char { shift if @_ == 3; my ($fd, $data) = @_; lcdPutchar($fd, $data); }
A short C program which prints out the proper custom character to my LCD:
#include <stdio.h> #include <wiringPi.h> #include <lcd.h> int main (int argc, char *argv[]){ unsigned char newChar [8] = { 0b11111, 0b10001, 0b10001, 0b10101, 0b11111, 0b10001, 0b10001, 0b11111, }; wiringPiSetupGpio(); static int fd; fd = lcdInit(2, 16, 4, 23, 16, 5, 6, 13, 19, 0, 0, 0, 0); lcdClear(fd); lcdPosition(fd, 0, 0); lcdCharDef(fd, 2, newChar); lcdPutchar(fd, 2); sleep(1); return 0; }
...and the Perl code that *should* do the same thing (print the custom char):
use warnings; use strict; use WiringPi::API qw(:all); setup_gpio(); my %args = ( cols => 16, rows => 2, bits => 4, rs => 23, strb => 16, d0 => 5, d1 => 6, d2 => 13, d3 => 19, d4 => 0, d5 => 0, d6 => 0, d7 => 0, ); my $fd = lcd_init(%args); my $def = [ 0b11111, 0b10001, 0b10001, 0b10101, 0b11111, 0b10001, 0b10001, 0b11111, ]; lcd_clear($fd); lcd_position($fd, 0, 0); lcd_char_def($fd, 2, $def); lcd_put_char($fd, 2); sleep 1;
Is there anything glaring that I'm missing? All of my other Perl code works fine (ie. all wrapped C functions work properly in all other cases. It's just one or both of these two that don't).
In reply to [SOLVED (workaround)]: External C function called through XS not Doing The Right Thing by stevieb
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |