==== Porting I/O Control Driver ==== The I/O control driver is built as a module, can be used for controlling common peripherals, such as LED, push button, buzzer. Copy [[http://dl.cubieboard.org/parteners/waveshare/Source_Code/Driver%20and%20API/Driver/|io_control_dev]] to your ubuntu system, compile it with your own system setting (refer to Appendix 1 "Compiling Driver Module"), and copy the generated io_control.ko file to the board, use the following command to load the driver module: $insmod io_control.ko Now you can start to try the I/O control API demo (refer to Appendix 2 "Running API Demo"). The buzzer can be shut up via configuring the related I/O port. Config the script.fex as follows: [lcd0_para] lcd_gpio_0 = port:PH15<0><0> Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Reboot the system to apply new configuration. ==== Porting Dallas’s 1-wire Driver ==== === Config the Kernel === Config the kernel to include Dallas’s 1-wire(DS18B20) driver. Under the root directory, enter the following commnad: #make menuconfig (All the make menuconfig that follows in this document, is executed under root directory) Config as follows: Device Drivers ---> <*> Dallas's 1-wire support ---> 1-wire Bus Masters ---> <*> GPIO 1-wire busmaster 1-wire Slaves ---> <*> Thermal family implementation Save and exit, re-compile the kernel: #make uImage Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] === Config the script.fex === Config the script.fex as follows, add the [w1_para] setting: [w1_para] w1_used = 1 w1_pin = port:PB10<1> Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Reboot the system, insert the DS18B20 device. Copy [[http://dl.cubieboard.org/parteners/waveshare/Source_Code/Driver%20and%20API/Driver/|ds18b20l_dev]] to your ubuntu system, compile it with your own system setting (refer to Appendix 1 "Compiling Driver Module"), and copy the generated w1-sunsi.ko file to the board, use the following command to load the driver: $insmod io_control.ko Enter the /sys/bus/w1/devices/w1_bus_master1 directory, there's a folder with the name preceding with "28-", which represents the DS18B20 device. The 28 means the current temperature sensor is DS18B20, the characters/numbers string follows stands for the device unique ID. Enter the folder, you should find it's device file named w1_slave, to get current temperature, enter this command on the terminal: $cat w1_slave As shown in the picture below: {{.:Documentations-6_1.jpg}} ==== Porting I2C Bus Driver ==== === Config the Kernel === Config the kernel to include I2C bus driver: #make menuconfig Device Drivers ---> {*} I2C support ---> I2C Hardware Bus support ---> <*> Allwinner Technology SUNXI I2C interface Save and exit. Comment out lines 914 to 918 of the i2c-sunxi.c file, which is located in drivers/i2c/busses directory, as follows: 914 /* else if (ret != num){ 915 printk("incomplete xfer (0x%x)\n", ret); 916 ret = -ECOMM; 917 //dev_dbg(i2c->adap.dev, "incomplete xfer (%d)\n", ret); 918 }*/ Save, and re-compile the kernel: #make uImage Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document <4. Prepare for Kernel and Drivers Porting>) === Config the script.fex === Our AT24/FM24 module can be used to test the I2C driver, which is connected to the I2C1 controller. Therefore, config the [twi1_para] setting in the script.fex as follows: [twi1_para] twi1_used = 1 twi1_scl = port:PB18<2> twi1_sda = port:PB19<2> Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Reboot the system. For more info about testing the AT24/FM24 module, like reading/writing data, please refer to the document [[tutorials:DVK521:Documentations:DVK521 User Manual|DVK521 User Manual]] and Appendix 2 "Running API Demo". ==== Porting SPI Devices Driver ==== === Config the Kernel === Config the kernel to include SPI driver: #make menuconfig Device Drivers ---> [*] SPI support ---> <*> SUN4I SPI Controller [*] SUN4I SPI Normal DMA mode select <*> DesignWare SPI controller core support <*> User mode SPI device driver support Save and exit, re-compile the kernel: #make uImage Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] === Config the script.fex === Our SPI module AT45DBXX DataFlash Board is connected to the SPI0 controller, therefore, config the [spi0_para], [spi_devices], and [spi_board0] settings in the script.fex as follows: [spi0_para] spi_used = 1 spi_cs_bitmap = 1 spi_cs0 = port:PI10<2> spi_sclk = port:PI11<2> spi_mosi = port:PI12<2> spi_miso = port:PI13<2> [spi_devices] spi_dev_num = 1 [spi_board0] modalias = "spidev" max_speed_hz = 12000000 bus_num = 0 chip_select = 0 mode = 3 full_duplex = 0 manual_cs = 0 Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Now the kernel and script.fex configuration for SPI device have completed, the last step is to load the io_control.ko driver module (refer to the previous section " Porting I/O Control Driver"). Reboot the system. Now you can use the AT45DBXX DataFlash Board to test the SPI driver (refer to Appendix 2 "Running API Demo"). ==== Porting LCD Driver ==== === Config the Kernel === The LCD driver support has been included in linux-sunxi-sunxi-3.4.61, the driver file can be found on drivers/video/sunxi/lcd. Check the kernel configuration, confirm that the driver is included: #make menuconfig Device Drivers ---> Graphics support ---> {*} Support for frame buffer devices ---> <*> DISP Driver Support(sunxi) -*- Reserve memory block for sunxi/fb [*] Enable FB/UMP Integration <*> LCD Driver Support(sunxi) <*> HDMI Driver Support(sunxi) Save and exit, re-compile the kernel: #make uImage Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] === Config the script.fex === The A10 supports two channel video output, however, only LCD0 is available on Cubieboard, therefore, we connect the 7inch capacitive LCD to the LCD0 controller. Config the script.fex, [dis_init] setting for display device initialization, and [lcd0_para] setting for LCD parameters (depending on the specifications of concrete LCD), as follows: [disp_init] disp_init_enable = 1 disp_mode = 0 screen0_output_type = 1 screen0_output_mode = 4 screen1_output_type = 1 screen1_output_mode = 4 fb0_framebuffer_num = 2 fb0_format = 10 fb0_pixel_sequence = 0 fb0_scaler_mode_enable = 0 fb1_framebuffer_num = 2 fb1_format = 10 fb1_pixel_sequence = 0 fb1_scaler_mode_enable = 0 lcd0_bright = 197 lcd1_bright = 197 lcd0_screen_bright = 50 lcd0_screen_contrast = 50 lcd0_screen_saturation = 57 lcd0_screen_hue = 50 lcd1_screen_bright = 50 lcd1_screen_contrast = 50 lcd1_screen_saturation = 57 lcd1_screen_hue = 50 [lcd0_para] lcd_used = 1 lcd_x = 800 lcd_y = 480 lcd_dclk_freq = 33 lcd_pwm_not_used = 0 lcd_pwm_ch = 0 lcd_pwm_freq = 10000 lcd_pwm_pol = 0 lcd_if = 0 lcd_hbp = 215 lcd_ht = 1055 lcd_vbp = 34 lcd_vt = 1050 lcd_hv_if = 0 lcd_hv_smode = 0 lcd_hv_s888_if = 0 lcd_hv_syuv_if = 0 lcd_hv_vspw = 0 lcd_hv_hspw = 48 lcd_lvds_ch = 0 lcd_lvds_mode = 0 lcd_lvds_bitwidth = 0 lcd_lvds_io_cross = 0 lcd_cpu_if = 0 lcd_frm = 0 lcd_io_cfg0 = 268435456 lcd_gamma_correction_en = 0 lcd_gamma_tbl_0 = 0x0 lcd_gamma_tbl_1 = 0x10101 lcd_gamma_tbl_255 = 0xffffff lcd_bl_en_used = 1 lcd_bl_en = port:PH07<1><0><1> lcd_power_used = 1 lcd_power = port:PH08<1><0><1> lcd_pwm_used = 1 lcd_pwm = port:PB02<2> lcd_gpio_0 = port:PH15<0><0> lcd_gpio_1 = lcd_gpio_2 = lcd_gpio_3 = lcdd0 = port:PD00<2><0> lcdd1 = port:PD01<2><0> lcdd2 = port:PD02<2><0> lcdd3 = port:PD03<2><0> lcdd4 = port:PD04<2><0> lcdd5 = port:PD05<2><0> lcdd6 = port:PD06<2><0> lcdd7 = port:PD07<2><0> lcdd8 = port:PD08<2><0> lcdd9 = port:PD09<2><0> lcdd10 = port:PD10<2><0> lcdd11 = port:PD11<2><0> lcdd12 = port:PD12<2><0> lcdd13 = port:PD13<2><0> lcdd14 = port:PD14<2><0> lcdd15 = port:PD15<2><0> lcdd16 = port:PD16<2><0> lcdd17 = port:PD17<2><0> lcdd18 = port:PD18<2><0> lcdd19 = port:PD19<2><0> lcdd20 = port:PD20<2><0> lcdd21 = port:PD21<2><0> lcdd22 = port:PD22<2><0> lcdd23 = port:PD23<2><0> lcdclk = port:PD24<2><0> lcdde = port:PD25<2><0> lcdhsync = port:PD26<2><0> lcdvsync = port:PD27<2><0> Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document <4. Prepare for Kernel and Drivers Porting>) Reboot the system, the LCD should be ready to work. ==== Porting CTP Driver ==== === Config the Kernel === linux-sunxi-sunxi-3.4.61 includes several capacitive touch panel drivers, such as FT5206/FT5406 driver, Goodix driver. The driver file can be found on drivers/input/touchscreen. Config the Kernel to include touchscreen driver: #make menuconfig Device Drivers ---> Input device support ---> [*] Touchscreens ---> <*> ft5x touchscreen driver Re-compile the kernel: #make uImage Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] === Config the script.fex === Since the touch screen is connected to I2C1 controller, make sure the I2C driver has been ported (refer to the previous section "Porting I2C Bus Driver"). Config the [ctp_para] setting in script.fex. ctp_name:driver name ctp_twi_id:I2C controller which is actually used ctp_twi_addr:I2C device address (7bit) ctp_screen_max_x:touch panel resolution ctp_screen_max_y:touch panel resolution ctp_revert_x_flag:set 1 to revert x axis ctp_revert_y_flag:set 1 to revert y axis ctp_exchange_x_y_flag:set 1 to exchange x axis and y axis ctp_int_port:touch interrupt pin ctp_wakeup:touch wakeup pin ctp_io_port:interrupt pin configuration According to the specifications and hardware connection of our 7inch capacitive LCD, config as follows: [ctp_para] ctp_used = 1 ctp_name = "ft5x_ts" ctp_twi_id = 1 ctp_twi_addr = 0x38 ctp_screen_max_x = 800 ctp_screen_max_y = 480 ctp_revert_x_flag = 0 ctp_revert_y_flag = 1 ctp_exchange_x_y_flag = 0 ctp_int_port = port:PH7<6> ctp_wakeup = port:PB13<1><1> ctp_io_port = port:PH7<0> Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Connect the 7inch capacitive LCD, reboot the system, try to touch the icons on the screen. ==== Porting VGA Driver ==== VAG driver has been includes in the kernel, just config the script.fex directly: [disp_init] disp_init_enable = 1 disp_mode = 0 screen0_output_type = 4 screen0_output_mode = 4 screen1_output_type = 2 screen1_output_mode = 14 fb0_framebuffer_num = 2 fb0_format = 10 fb0_pixel_sequence = 0 fb0_scaler_mode_enable = 1 fb1_framebuffer_num = 2 fb1_format = 10 fb1_pixel_sequence = 0 fb1_scaler_mode_enable = 1 Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document <4. Prepare for Kernel and Drivers Porting>) Reboot the system, now the VGA can be used for displaying. ==== Porting HDMI Driver ==== HDMI driver has been includes in the kernel, just config the script.fex directly: [disp_init] disp_init_enable = 1 disp_mode = 0 screen0_output_type = 3 screen0_output_mode = 5 screen1_output_type = 1 screen1_output_mode = 4 Reboot the system, now the HDMI can be used for displaying. ==== Porting CSI Driver === === Config the Kernel === #make menuconfig Device Drivers ---> <*> Multimedia support ---> <*> Video For Linux [*] CSI Driver Config for sun4i ---> OmniVision OV7670 sensor support Built the camera driver as module, save and exit. Comment out the print messages in the __s32 img_sw_para_to_reg(__u8 type, __u8 mode, __u8 value) function in disp_layer.c file, which is under drivers/video/sunxi/disp directory. Lines 95 to 99: 95 /* else { 96 DE_WRN("not supported yuv channel format:%d in " 97 "img_sw_para_to_reg\n", value); 98 return 0; 99 }*/ Lines 125 to 129: 125 /* else { 126 DE_WRN("not supported yuv channel pixel sequence:%d " 127 "in img_sw_para_to_reg\n", value); 128 return 0; 129 }*/ Lines 168 to 172: 168 /* else { 169 DE_WRN("not supported image0 pixel sequence:%d in " 170 "img_sw_para_to_reg\n", value); 171 return 0; 172 }*/ Line 175: 175 // DE_WRN("not supported type:%d in img_sw_para_to_reg\n", type); Save, re-compile the kernel: #make uImage Compile the kernel modules: #make modules Install the kernel modules: #make modules_install The installation copies the compiled kernel module from the kernel source code to the ubuntu /lib/modules directory. The related driver module files include: videobuf-core.ko, videobuf-dma-contig.ko, sun4i_csi1.ko, ov7670.ko, which are located respectively in: videobuf-core.ko, videobuf-dma-contig.ko: /lib/modules/3.4.61+/kernel/drivers/media/video ov7670.ko: /lib/modules/3.4.61+/kernel/drivers/media/video/sun4i_csi/device sun4i_csi1.ko: /lib/modules/3.4.61+/kernel/drivers/media/video/sun4i_csi/csi1 Replace the earlier uImage on the board with the new generated uImage under arch/arm/boot/ directory via NFS. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Copy the above 4 driver files to the board, and install them in order: $insmod videobuf-core.ko $insmod videobuf-dma-contig.ko $insmod ov7670.ko $insmod sun4i_csi1.ko Note: please pay attention to the installing order, camera driver should be installed before sun4i_csi1.ko. === Config the script.fex === Since our OV7670 camera is connected to the CSI1 controller, config the [csi1_para] setting in script.fex. The suffix _b in the parameter name indicates that this is a secondary camera parameter while two cameras were connected to the same CSI. The parameters are interpreted as follows: csi_used = xx:enable/disable csi0 or csi1 csi_mode = xx:CSI receiver buffer mode: 0:a stand-alone buffer for each CSI receiver 1:a shared buffer for both CSI receiver csi_dev_qty = xx:CSI device quantity, 1 or 2 csi_stby_mode = xx:standby power statue 0:power on when standby 1:power off when standby csi_mname = “xxx”: CSI module name, matches with the driver, valid option includes: ov7670/gc0308/gt2005/hi704/sp0338/mt9m112/gc0307/mt9m113/mt9d112/hi253/ov5640 csi_twi_id = xx:I2C csi_twi_addr = xx:I2C address csi_if = xx:interface timing: 0:8bit data line, with Hsync,Vsync 1:16bit data line, with Hsync,Vsync 2:24bit data line, with Hsync,Vsync 3:8bit data line, BT656 embedded sync, single-channel 4:8bit data line, BT656 embedded sync, dual-channels 5:8bit data line, BT656 embedded sync, four-channels csi_vflip = xx:video vertical flip 0:normal 1:flip csi_hflip = xx:video horizontal flip 0:normal 1:flip csi_iovdd = "", csi_avdd = "", and csi_dvdd = "": power supply of the camera module's IO, Analog, and Core. "axp20_pll": powering from AXP20 LDO3 "axp20_hdmi": powering from AXP20 LDO4 "": powering from other source csi_flash_pol = xx:flash polarity for cameras that feature flash IO control 0: flash lights when IO low level 1: flash lights when IO high level csi_pck = xx:GPIO configuration for clock signal from module to CSI csi_ck = xx:GPIO configuration for clock signal from CSI to module csi_hsync = xx:GPIO configuration for horizontal sync signal from module to CSI csi_vsync = xx:GPIO configuration for vertical sync signal from module to CSI csi_d0 = xx to csi_d15 = xx:GPIO configuration for 8bit/16bit data from module to CSI csi_reset = xx:GPIO configuration for module reset csi_power_en = xx:GPIO configuration for module power, high active by default csi_stby = xx:GPIO configuration for module standby csi_af_en = xx:GPIO configuration for module AF power The details configuration: [csi1_para] csi_used = 1 csi_mode = 0 csi_dev_qty = 1 csi_stby_mode = 0 csi_mname = "ov7670" csi_twi_id = 1 csi_twi_addr = 0x42 csi_if = 0 csi_vflip = 1 csi_hflip = 0 csi_iovdd = "" csi_avdd = "" csi_dvdd = "" csi_flash_pol = 1 csi_mname_b = "" csi_twi_id_b = 0 csi_twi_addr_b = 0x78 csi_if_b = 0 csi_vflip_b = 1 csi_hflip_b = 0 csi_iovdd_b = "" csi_avdd_b = "" csi_dvdd_b = "" csi_flash_pol_b = 1 csi_pck = port:PG00<3> csi_ck = port:PG01<3> csi_hsync = port:PG02<3> csi_vsync = port:PG03<3> csi_field = csi_d0 = port:PG04<3> csi_d1 = port:PG05<3> csi_d2 = port:PG06<3> csi_d3 = port:PG07<3> csi_d4 = port:PG08<3> csi_d5 = port:PG09<3> csi_d6 = port:PG10<3> csi_d7 = port:PG11<3> csi_d8 = csi_d9 = csi_d10 = csi_d11 = csi_d12 = csi_d13 = csi_d14 = csi_d15 = csi_d16 = csi_d17 = csi_d18 = csi_d19 = csi_d20 = csi_d21 = csi_d22 = csi_d23 = csi_reset = port:PH14<1><0> csi_power_en = csi_stby = port:PH17<1><0> csi_flash = csi_af_en = csi_reset_b = csi_power_en_b = csi_stby_b = csi_flash_b = csi_af_en_b = Then convert it into script.bin format by using fex2bin, and replace the earlier script.bin on the board. (for more info, refer to the document [[tutorials:DVK521:Documentations:Prepare for Kernel and Drivers Porting|Prepare for Kernel and Drivers Porting]] Connect the OV7670 camera module and the LCD to the board, reboot the system. Now you can start to try the camera API demo (refer to Appendix 2 "Running API Demo"). ==== Appendix 1: Compiling Driver Module ==== The provided xx.ko files under [[http://dl.cubieboard.org/parteners/waveshare/Source_Code/Driver%20and%20API/Driver/|Driver]] is compiled to run on our system image only. If the drivers are going to being loaded on your own system, they need to be re-compiled according to you system kernel path. Use the io_control_dev.ko for demonstration. 1.1 Copy the [[http://dl.cubieboard.org/parteners/waveshare/Source_Code/Driver%20and%20API/Driver/|io_control_dev]] to ubuntu, assume the target directory is /home/waveshare/cubieboard/waveshare_demo/driver . Modify the files permission: #cd /home/waveshare/cubieboard/waveshare_demo/driver/io_control_dev {{.:Documentations-6_2.jpg}} #chmod 777 ./* 1.2 Modify the Makefile #vi Makefile {{.:Documentations-6_3.jpg}} Assign the KERNELDIR according to your actual kernel path. 1.3 Clear the old files #make clean {{.:Documentations-6_4.jpg}} 1.4 Compile #make An error might occur while compiling: io_control.c:1:23: fatal error: linux/init.h: No such file or directory compilation terminated. make: *** [modules] Error 1 As shown in the picture below: {{.:Documentations-6_5.jpg}} It is caused by the different kernel version, can be just omitted. {{.:Documentations-6_6.jpg}} Copy the new generated io_control.ko file to your own system and load it. ==== Appendix 2 "Running API Demo" ==== When the driver has been loaded, you can start to try the API demo. Copy the API source code to your ubuntu, and modify the files permission: #chmod 777 ./* Execute the following command to compile: #make Then copy the executable file to the board, say, "test_led", use the following command to run it: #./ test_led