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.