Quantcast
Channel: Forums - Recent Threads
Viewing all articles
Browse latest Browse all 262198

Linux/AM3359: Using I2C in Kernel space with AM3359 ICE V2

$
0
0

Part Number:AM3359

Tool/software: Linux

Hello,

I want to communicate with an I2C device through pins 4 and 6 of connector J3 of AM3359 ICE V2 in Kernel space. I am trying to do it by directly modifying the registers. Here is my code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <asm/io.h>		// For iomap

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vincent Paratte");
MODULE_DESCRIPTION("I2C test");
MODULE_VERSION("0.1");

#define BASE_ADDRESS 0x44E0B000		// Initial address for the memory mapping
#define BASE_SIZE 0x100			// Size of the memory mapped address
#define PRESCALER 0x1			// Prescaler to set clock to 12 MHz instead of 24 MHz
#define PRESCALER_OFFSET 0xB0		// Offset from BASE_ADDRESS for I2C_PSC register
#define SCLL 0x8			// Define t_low clock time (SCK) to 1.25 us (400 Kbps): 1.25u*12M-7
#define SCLL_OFFSET 0xB4		// Offset from BASE_ADDRESS for I2C_SCLL register
#define SCLH 0xA			// Define t_low clock time (SCK) to 1.25 us (400 Kbps): 1.25u*12M-5
#define SCLH_OFFSET 0xB8		// Offset from BASE_ADDRESS for I2C_SCLH register
#define CONF_RECEIVER 0x10000		// Config to have 7-bit address mode, master mode, enable I2C and switch to receiver mode
#define CONF_TRANSCEIVER 0x10100	// Config to have 7-bit address mode, master mode, enable I2C and switch to transceiver mode
#define CONF_OFF 0x0			// Config to disable I2C
#define CONF_OFFSET 0xA4		// Offset from BASE_ADDRESS for I2C_CON register
#define SLAVE_ADDRESS 0x55		// Slave address
#define SLAVE_ADDRESS_OFFSET 0xAC	// Offset from BASE_ADDRESS for I2C_SA register
#define NBR_BYTE 0x2			// Set the number of byte to read/write in a raw
#define NBR_BYTE_OFFSET 0x98		// Offset from BASE_ADDRESS for I2C_CNT register
#define BUSY_OFFSET 0x24		// Offset from BASE_ADDRESS to access IRQSTATUS_RAW register (bit 12 high if bus busy)
#define DATA_OFFSET 0x9C		// Offset from BASE_ADDRESS to access data (bit 0-7)

static void __iomem *base;

static int __init i2c_init(void)
{
	static u8 counter = 0;
	static u8 data = 0xAA;
	static u32 busy = 0;

	// Configuration of I2C

	printk("Starting configuration of I2C bus\n");

	base = ioremap(BASE_ADDRESS, BASE_SIZE);	// Memory mapping to have acces to the registers
	iowrite32(PRESCALER, base + PRESCALER_OFFSET);	// Set the clock to 12 MHz
	iowrite32(SCLL, base + SCLL_OFFSET);		// Set to 400 Kbps by applying t_High = t_Low = 2.5 us
	iowrite32(SCLH, base + SCLH_OFFSET);
	iowrite32(CONF_RECEIVER, base + CONF_OFFSET);	// Set up I2C as a receiver master
	iowrite32(SLAVE_ADDRESS, base + SLAVE_ADDRESS_OFFSET);	// Set the address of the slave device
	iowrite32(NBR_BYTE, base + NBR_BYTE_OFFSET);	// Set the number of byte to read/write in a raw to 2 (8 bit)

	printk("Configuration done\n");
	iowrite32(CONF_TRANSCEIVER, base + CONF_OFFSET);	// Set as a transceiver
	printk("Transceiver mode activated!\n");
	
	while (counter < 10)
	{
		busy = ioread16(base + CONF_OFFSET);		// Read BUSY bit to now if the bus is busy
		if (((busy && 0x1000) >> 12) == 0)		// If busy bit = 0 -> bus not busy
		{
			printk("Bus empty\n");
			mdelay(1000);
			iowrite32(data, base + DATA_OFFSET);	// Write the data
			printk("AA written\n");
			mdelay(1000);
		}
		else printk("Bus busy\n");
		counter ++;
		mdelay(2000);
	}
	return 0;
}

static void __exit i2c_exit(void)
{
	iowrite8(CONF_OFF, base + CONF_OFFSET);	// Stop I2C
	iounmap(base);				// Free the mapping
	printk("Exiting module\n");
}

module_init(i2c_init);
module_exit(i2c_exit);

The code compile correctly with make but when I send it with insmod, it stops after the line << printk("Transceiver mode activated!\n"); >>

I guess with the error message that I try to read (with ioread16) an address that does not exist but I double check the number of the registers and it seems to be all right.

Here is answer to my code:

 insmod I2C.ko
[   43.447017] Starting configuration of I2C bus
[   43.451574] Configuration done
[   43.454646] Transceiver mode activated!
[   43.473560] Unhandled fault: external abort on non-linefetch (0x1028) at 0xf9e0b0d1
[   43.473567] pgd = ce0f8000
[   43.473578] [f9e0b0d1] *pgd=44e11452(bad)
[   43.473591] Internal error: : 1028 [#1] PREEMPT ARM
[   43.473720] Modules linked in: I2C(O+) pvrsrvkm(O) pru_rproc pruss_intc pruss sha512_generic sha512_arm sha256_generic sha1_generic sha1_arm_neon sha1_arm md5 ti_am335x_adc des_generic cbc g_multi usb_f_mass_storage usb_f_rndis u_ether libcomposite udc_core usb_common xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo bluetooth wkup_m3_rproc pm33xx wkup_m3_ipc omap_aes_driver remoteproc omap_sham crypto_engine ti_emif_sram pruss_soc_bus c_can_platform c_can can_dev gpio_pca953x gpio_tpic2810 gpio_pisosr rtc_omap omap_wdt ti_am335x_tscadc gpio_decoder input_polldev sch_fq_codel uio_module_drv(O) uio cryptodev(O)
[   43.473738] CPU: 0 PID: 836 Comm: insmod Tainted: G        W  O    4.9.59-rt23-g273202a0d3 #10
[   43.473742] Hardware name: Generic AM33XX (Flattened Device Tree)
[   43.473748] task: ce7e8d00 task.stack: ce6b6000
[   43.473771] PC is at do_alignment_ldrhstrh+0x3c/0x124
[   43.473777] LR is at 0x1
[   43.473785] pc : [<c01152a0>]    lr : [<00000001>]    psr: 000f0113
[   43.473785] sp : ce6b7bb8  ip : 00000003  fp : ce6b7bcc
[   43.473790] r10: 00000000  r9 : 00000004  r8 : 00000001
[   43.473795] r7 : f9e0b0d1  r6 : bf2600e4  r5 : c0c492cc  r4 : 00000003
[   43.473801] r3 : 00000000  r2 : ce6b7d50  r1 : e1d330b0  r0 : f9e0b0d1
[   43.473809] Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   43.473815] Control: 10c5387d  Table: 8e0f8019  DAC: 00000051
[   43.473821] Process insmod (pid: 836, stack limit = 0xce6b6208)
[   43.473826] Stack: (0xce6b7bb8 to 0xce6b8000)
[   43.473836] 7ba0:                                                       ce6b7d50 c0c492cc
[   43.473850] 7bc0: ce6b7c9c ce6b7bd0 c0115c34 c0115270 00000000 00000001 ce6b7bf4 ce6b7be8
[   43.473863] 7be0: c047a060 c0501cb4 00007c54 e1d330b0 c047cdfc c047a040 ce6b7c10 c01618d8
[   43.473876] 7c00: c03b1c24 c098eb7c 0000002b 0006eff6 c0c553a8 c0c4cbd0 00000000 c0c4cbd0
[   43.473889] 7c20: ce6b7c4c ce6b7c30 c0161978 c016185c c0c2c568 c0c4c6c0 0000002b c0c6cffc
[   43.473902] 7c40: 00000000 00000000 ce6b7c64 ce6b7c58 c0477ff8 c047cce8 ce6b7c8c ce6b7c68
[   43.473916] 7c60: ce6b7c7c ce6b7c70 c01a09e0 c01883dc ce6b7c8c 00000001 c0115b24 f9e0b0d1
[   43.473929] 7c80: c0c086b0 ce6b7d50 ce6b6000 ce1e3948 ce6b7d4c ce6b7ca0 c0101308 c0115b30
[   43.473942] 7ca0: 600f0013 c0c12140 00000000 00000007 c0c4c6c0 00000000 00000189 00000000
[   43.473954] 7cc0: 600f0013 00000000 0000001b 00000002 00000004 c0c12140 00000000 00000000
[   43.473967] 7ce0: ce6b7d4c ce6b7cf0 c0164054 c016363c 00000000 00000000 00000000 00000000
[   43.473980] 7d00: c0c6effc 0000001b c0c6e638 c0c4c6c0 00000000 00000000 600f0013 00000000
[   43.473993] 7d20: c0656b30 c01643f0 f9e0b02d bf2600e4 600f0013 ffffffff ce6b7d84 bf260000
[   43.474006] 7d40: ce6b7dc4 ce6b7d50 c010c138 c01012d4 0000001b c0c121dc 00000000 f9e0b0d1
[   43.474019] 7d60: bf25e2c0 f9e0b02d ce1e3180 bf25e100 bf260000 00000000 ce1e3948 ce6b7dc4
[   43.474032] 7d80: ce6b7c70 ce6b7da0 c01a09e0 bf2600e8 600f0013 ffffffff 00000051 bf000000
[   43.474045] 7da0: bf25e100 00000001 ce1e3180 bf25e100 bf260000 00000000 ce6b7e44 ce6b7dc8
[   43.474059] 7dc0: c01016f8 bf26000c ce1e3180 d0e85000 00000000 00000001 ce6b7e24 ce6b7de8
[   43.474071] 7de0: c01bdf50 c0780f48 c01edd4c c03bb080 00000001 00000001 ce1e3964 00000000
[   43.474085] 7e00: ce1e3180 d0e85000 ce6b7e44 ce6b7e18 c01fb950 c02052f4 c0c748dc bf25e100
[   43.474098] 7e20: 00000001 ce1e3180 bf25e100 00000001 ce1e3964 ce1e3948 ce6b7e6c ce6b7e48
[   43.474111] 7e40: c01b483c c01016bc ce1e3940 bf25e100 ce6b7e6c ce6b7f44 00000001 ce1e3940
[   43.474124] 7e60: ce6b7f1c ce6b7e70 c01910a4 c01b47e0 bf25e10c 00007fff bf25e100 c018e7c0
[   43.474138] 7e80: 00000001 d0e85000 bf25e10c bf25e10c bf25e2c8 bf25e298 bf25e148 bf25e214
[   43.474151] 7ea0: ce6b7eec ce6b7eb0 c0212a68 c02123b0 d0e85000 00000000 00000000 00000000
[   43.474163] 7ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   43.474175] 7ee0: 00000000 00000000 00000000 00000000 7fffffff 7fffffff 00000000 00000000
[   43.474188] 7f00: 00027dc4 c0107b04 ce6b6000 00000000 ce6b7fa4 ce6b7f20 c01916dc c018f550
[   43.474201] 7f20: 7fffffff 00000000 00000003 ce6b7f38 c01d3c98 d0e85000 00001160 00000000
[   43.474214] 7f40: 00000000 d0e85000 00001160 d0e85e40 d0e85d7c d0e85ad0 000002c8 000003e8
[   43.474227] 7f60: 00000000 00000000 00000000 0000065c 00000012 00000013 0000000b 00000009
[   43.474240] 7f80: 00000007 00000000 0003a008 00000000 00025a74 0000017b 00000000 ce6b7fa8
[   43.474253] 7fa0: c0107940 c0191654 0003a008 00000000 00000003 00027dc4 00000000 00000000
[   43.474265] 7fc0: 0003a008 00000000 00025a74 0000017b 00000000 00000002 b6fe0000 00000000
[   43.474278] 7fe0: bef7cae8 bef7cad8 0001f57c b6f3a9f2 80070030 00000003 00000000 00000000
[   43.474283] Backtrace:
[   43.474302] [<c0115264>] (do_alignment_ldrhstrh) from [<c0115c34>] (do_alignment+0x110/0x738)
[   43.474310]  r5:c0c492cc r4:ce6b7d50
[   43.474323] [<c0115b24>] (do_alignment) from [<c0101308>] (do_DataAbort+0x40/0xbc)
[   43.474336]  r10:ce1e3948 r9:ce6b6000 r8:ce6b7d50 r7:c0c086b0 r6:f9e0b0d1 r5:c0115b24
[   43.474340]  r4:00000001
[   43.474351] [<c01012c8>] (do_DataAbort) from [<c010c138>] (__dabt_svc+0x58/0x80)
[   43.474356] Exception stack(0xce6b7d50 to 0xce6b7d98)
[   43.474364] 7d40:                                     0000001b c0c121dc 00000000 f9e0b0d1
[   43.474377] 7d60: bf25e2c0 f9e0b02d ce1e3180 bf25e100 bf260000 00000000 ce1e3948 ce6b7dc4
[   43.474388] 7d80: ce6b7c70 ce6b7da0 c01a09e0 bf2600e8 600f0013 ffffffff
[   43.474399]  r8:bf260000 r7:ce6b7d84 r6:ffffffff r5:600f0013 r4:bf2600e4
[   43.474428] [<bf260000>] (i2c_init [I2C]) from [<c01016f8>] (do_one_initcall+0x48/0x178)
[   43.474440]  r9:00000000 r8:bf260000 r7:bf25e100 r6:ce1e3180 r5:00000001 r4:bf25e100
[   43.474463] [<c01016b0>] (do_one_initcall) from [<c01b483c>] (do_init_module+0x68/0x1cc)
[   43.474476]  r10:ce1e3948 r9:ce1e3964 r8:00000001 r7:bf25e100 r6:ce1e3180 r5:00000001
[   43.474480]  r4:bf25e100
[   43.474497] [<c01b47d4>] (do_init_module) from [<c01910a4>] (load_module+0x1b60/0x1fc0)
[   43.474505]  r6:ce1e3940 r5:00000001 r4:ce6b7f44
[   43.474517] [<c018f544>] (load_module) from [<c01916dc>] (SyS_finit_module+0x94/0xa4)
[   43.474530]  r10:00000000 r9:ce6b6000 r8:c0107b04 r7:00027dc4 r6:00000000 r5:00000000
[   43.474533]  r4:7fffffff
[   43.474550] [<c0191648>] (SyS_finit_module) from [<c0107940>] (ret_fast_syscall+0x0/0x44)
[   43.474559]  r7:0000017b r6:00025a74 r5:00000000 r4:0003a008
[   43.474572] Code: 0a00000c e2113601 0a000032 e3a03000 (e4d0c001)
Segmentation fault

Broadcast message from systemd-journald@am335x-evm (Sat 2017-12-23 13:52:49 UTC):

kernel[318]: [   43.473591] Internal error: : 1028 [#1] PREEMPT ARM


Broadcast message from systemd-journald@am335x-evm (Sat 2017-12-23 13:52:49 UTC):

kernel[318]: [   43.473821] Process insmod (pid: 836, stack limit = 0xce6b6208)


Broadcast message from systemd-journald@am335x-evm (Sat 2017-12-23 13:52:49 UTC):

kernel[318]: [   43.473826] Stack: (0xce6b7bb8 to 0xce6b8000)


Broadcast message from systemd-journald@am335x-evm (Sat 2017-12-23 13:52:49 UTC):

kernel[318]: [   43.473836] 7ba0:                                                       ce6b7d50 c0c492cc

Does anybody know what is wrong? I never changed the I2C part of the dts file and I2C was working in user space with I2C-dev.


Viewing all articles
Browse latest Browse all 262198

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>