- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all, I've trayed to make a color space converter device to integrate in NiosII project. I follow this (http://www.nioswiki.com/accessing_hardware_registers_from_user_space_programs). This is my vhdl code :
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_unsigned.all;
use ieee.math_real.all;
entity csc_custom is
port(
signal clk : IN std_logic;
signal reset_n : IN std_logic;
-- interface Avalon ( Segnali per SOPC Builder)
signal chipselect : IN std_logic;
signal writedata : IN std_logic_vector(31 downto 0);
signal readdata : OUT std_logic_vector(31 downto 0);
signal write : IN std_logic);
end entity csc_custom;
architecture europa of csc_custom is
begin
process(clk, reset_n)
variable timestamp_write : std_logic_vector(31 downto 0);
variable timestamp_read : std_logic_vector(31 downto 0);
variable R : integer;
variable G : integer;
variable B : integer;
variable Y : integer;
variable Cr : integer;
variable Cb : integer;
variable tmp1 : unsigned (15 downto 0);
variable tmp2 : unsigned (15 downto 0);
variable tmp3 : unsigned (15 downto 0);
variable converted : boolean;
begin
if reset_n = '0' then
timestamp_write := (others => '0');
timestamp_read := (others => '0');
converted := FALSE;
elsif rising_edge(clk) then
if write = '1' and chipselect = '1' and converted = FALSE then
timestamp_write := writedata;
-- Qui faccio le diverse operazioni sui tre byte
R := conv_integer(unsigned(timestamp_write( 23 downto 16)));
G := conv_integer(unsigned(timestamp_write( 15 downto 8)));
B := conv_integer(unsigned(timestamp_write( 7 downto 0)));
Y := 66 * R + 129 * G + 25 * B;
Cb := -38 * R - 74 * G + 112 * B;
Cr := 112 * R - 94 * G - 18 * B;
tmp1 := conv_unsigned(Y,16) + 128;
timestamp_write( 23 downto 16) := conv_std_logic_vector(tmp1( 15 downto 8) + 16,8);
tmp2 := conv_unsigned(Cr,16) + 128;
timestamp_write( 15 downto 8) := conv_std_logic_vector(tmp2( 15 downto 8) + 128,8);
tmp3 := conv_unsigned(Cb,16) + 128;
timestamp_write( 7 downto 0) := conv_std_logic_vector(tmp3( 15 downto 8) + 128,8);
converted := TRUE;
timestamp_read := timestamp_write;
elsif write = '0' and chipselect = '1' and converted = TRUE then
readdata <= timestamp_read;
converted := FALSE;
end if;
end if;
end process;
end europa;
I've made a functional simulation with Quartus and the code seems work (when I write in Avalon, I make the conversion and when I read in Avalon, I read the converted value). This is my modified module driver : #include <linux/module.h># include <linux/kernel.h># include <linux/errno.h># include <linux/mm.h># include <linux/fs.h># include <linux/cdev.h>
# include <asm/io.h># include <asm/uaccess.h>
# include <asm-nios2/nios2.h>
# define DEBUG# undef DEBUG
# define CSC_CUSTOM_BASE_ADDR na_custom# define CSC_CUSTOM_SIZE 4
MODULE_AUTHOR("Stefano CAMPITELLI");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Module for Color Space Converter RGB->YUV /dev/csc_custom");
MODULE_SUPPORTED_DEVICE("none");
# define CSC_CUSTOM_MAJOR 251# define CSC_CUSTOM_MINOR 0
static int csc_custom_open(struct inode*, struct file*);
static int csc_custom_release(struct inode*, struct file*);
static int csc_custom_mmap(struct file *file, struct vm_area_struct * vma);
static unsigned long csc_custom_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags);
static struct csc_custom_dev_t
{
int __iomem* membase;
struct cdev cdev;
} s_csc_custom_dev;
/* definitions, which functions are called for /dev/csc */
static struct file_operations fops_csc_custom =
{
.mmap = csc_custom_mmap,
.open = csc_custom_open,
.release = csc_custom_release,
.get_unmapped_area = csc_custom_get_unmapped_area,
};
/* called when data device file is opened */
static int csc_custom_open(struct inode *inode, struct file *filp)
{
struct csc_custom_dev_t *dev = container_of(inode->i_cdev, struct csc_custom_dev_t, cdev);
filp->private_data = dev;
return 0;
}
/* called when process closes data device file */
static int csc_custom_release(struct inode *inode, struct file *filp)
{
return 0;
}
/* called when a process mmap from data file */
static int csc_custom_mmap(struct file *filp, struct vm_area_struct * vma)
{
struct csc_custom_dev_t *dev = (struct csc_custom_dev_t*)filp->private_data;
vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
vma->vm_start = (unsigned long)dev->membase;
vma->vm_end = vma->vm_start + CSC_CUSTOM_SIZE;
return 0;
}
static unsigned long csc_custom_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
{
return pgoff << PAGE_SHIFT;
}
static int __init mod_init(void)
{
int res;
dev_t devno = MKDEV(CSC_CUSTOM_MAJOR, CSC_CUSTOM_MINOR);
struct csc_custom_dev_t *dev = &s_csc_custom_dev;
cdev_init(&dev->cdev, &fops_csc_custom);
dev->cdev.owner = THIS_MODULE;
dev->membase = ioremap(CSC_CUSTOM_BASE_ADDR, CSC_CUSTOM_SIZE);
res = register_chrdev_region(devno, 1, "csc_custom");
if (res)
{
printk(KERN_NOTICE "Can't get major %d for CSC_CUSTOM", CSC_CUSTOM_MAJOR);
return res;
}
res = cdev_add(&dev->cdev, devno, 1);
if (res)
{
printk(KERN_NOTICE "Error %d adding CSC_CUSTOM", res);
unregister_chrdev_region(devno, 1);
return res;
}
printk(KERN_INFO "csc_custom: Color Space Converter (RGB->YUV) driver v0.0 (lug 2009) by campo85 at 0x%p\n",dev->membase);
return res;
}
/* exit the module */
static void __exit mod_exit(void)
{
cdev_del(&s_csc_custom_dev.cdev);
unregister_chrdev_region(MKDEV(CSC_CUSTOM_MAJOR, CSC_CUSTOM_MINOR), 1);
}
/* what are the module init/exit functions */
module_init(mod_init);
module_exit(mod_exit);
and now this is my test program : #include <unistd.h># include <fcntl.h># include <sys/mman.h># include <asm/types.h># include <stdio.h># include <stdlib.h>
static volatile unsigned long* pCsc = 0;
static int CscFd = -1;
/* init */
int CscInit()
{
if ((CscFd = open("/dev/csc_custom", O_RDWR)) != -1) {
pCsc = (unsigned long*)mmap(0, 4, PROT_READ | PROT_WRITE, MAP_SHARED, CscFd, 0);
if (pCsc == MAP_FAILED) return -1;
}
return CscFd;
}
/* utilization */
int GetYUV()
{
return *pCsc;
}
/* deInit */
int CscEnd()
{
if (pCsc != MAP_FAILED) munmap((void*)pCsc, 4);
if (CscFd != -1) close(CscFd);
return 0;
}
void GiveRGB(unsigned long *pRGB)
{
*pCsc = *pRGB;
return;
}
int main(int argc, char *argv)
{
CscInit();
__u8 *R,*G,*B,*Y,*Cr,*Cb;
unsigned long *tmp = (unsigned long *) malloc( sizeof(unsigned long));
int *tripletta = (int *) malloc(sizeof(int) * 3);
*tmp = 0;
B = (__u8 *) tmp;
G = B + 1;
R = B + 2;
*R = 23;
*G = 130;
*B = 100;
tripletta = *R;
tripletta = *G;
tripletta = *B;
printf("Tripletta RGB : %d %d %d\n",tripletta,tripletta,tripletta);
GiveRGB(tmp);
*tmp =(unsigned long) GetYUV;
Cb = (__u8 *) tmp;
Cr = Cb + 1;
Y = Cb + 2;
tripletta = *Y;
tripletta = *Cr;
tripletta = *Cb;
printf("Tripletta YCrCb : %d %d %d\n",tripletta,tripletta,tripletta);
*R = 0;
*G = 0;
*B = 0;
tripletta = *R;
tripletta = *G;
tripletta = *B;
printf("Tripletta RGB : %d %d %d\n",tripletta,tripletta,tripletta);
GiveRGB(tmp);
*tmp =(unsigned long) GetYUV;
Cb = (__u8 *) tmp;
Cr = Cb + 1;
Y = Cb + 2;
tripletta = *Y;
tripletta = *Cr;
tripletta = *Cb;
printf("Tripletta YCrCb : %d %d %d\n",tripletta,tripletta,tripletta);
*R = 255;
*G = 255;
*B = 255;
tripletta = *R;
tripletta = *G;
tripletta = *B;
printf("Tripletta RGB : %d %d %d\n",tripletta,tripletta,tripletta);
GiveRGB(tmp);
*tmp =(unsigned long) GetYUV;
Cb = (__u8 *) tmp;
Cr = Cb + 1;
Y = Cb + 2;
tripletta = *Y;
tripletta = *Cr;
tripletta = *Cb;
printf("Tripletta YCrCb : %d %d %d\n",tripletta,tripletta,tripletta);
free(tripletta);
CscEnd();
return 0;
}
When I try to run the test program I always receive the same wrong output. Someone can help me ?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What about debugging ? :)
If you want to invite somebody to help you you should post a very short code example that does not work. -Michael- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem is that I don't know what's part doesn't work. I think, that VHDL code (not integrated in Nios) works. I've made a functional simulation and it seems to be all ok (when write signal is high I convert the the RGB triple). So , maybe, is a software problem. The (test (http://pastebin.com/f3a79f68c)) was written in good part by me following this (http://www.nioswiki.com/accessing_hardware_registers_from_user_space_programs) . In your opinion where is the problem ( vhdl, module, test) ? Sorry for my horrible english and my ignorance, but I'm very newbe about module programming.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So I sugget that you first try to get going something simpler (i. e. accising a PIO bit I/O using the MMap driver).
-Michael- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I've resolved. The problem wereseveral. First one I've made some error during the creation of the node /dev/csc_custom. Then the test cose was incomplete. Thanks to everyone for help. Finally I finish my graduation thesis :lol: . Bye

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page