历史上的今天
今天是:2025年10月13日(星期一)
2022年10月13日 | mini2440 IIC 裸机程序记录
2022-10-13 来源:csdn
调了两天终于把2440上面的IIC调通了,代码记录如下:
head.s
@this is a test program of uart using com0, the properties of com0 is the same as usual (115200,8, 1, n, n)
.text
.global _start
_start:
b Reset
b . @undefined instruction
b . @swi
b . @pregetch instruction
b . @data abort
b . @Reserved
b HandleIRQ @irq
b . @fiq
Reset:
ldr sp, =4096 @set the stack pointer of sys mode to 4096
bl disable_watchdog
bl init_led
bl init_sdram
bl copy_sdram
ldr pc, =on_sdram
on_sdram:
msr cpsr_c, #0xd2 @set cpu to irq mode
ldr sp, =3072 @set the stack pointer of irq mode to 3072
msr cpsr_c, #0xdf @reset cpu to sys mode
bl init_clock
mov r0, #1
mov r1, #10
bl blink
bl init_iic
mov r0, #2
mov r1, #10
bl blink
bl init_com0
mov r0, #3
mov r1, #10
bl blink
bl init_irq
msr cpsr_c, #0x5f @enable irq
bl main
b .
.ltorg
.ltorg
.ltorg
HandleIRQ:
sub lr, lr, #4
stmdb sp!, {r0-r12, lr}
ldr lr, =next
ldr pc, =interrupt_func
next:
ldmia sp!, {r0-r12, pc}^ @return to main
.ltorg
.ltorg
init.c
#define GPBCON (*((volatile unsigned long*)(0x56000010)))
#define GPBDAT (*((volatile unsigned long*)(0x56000014)))
#define WTCON (*((volatile unsigned long*)(0x53000000)))
#define LOCKTIME (*((volatile unsigned long*)(0x4C000000)))
#define CLKDIVN (*((volatile unsigned long*)(0x4C000014)))
#define MPLLCON (*((volatile unsigned long*)(0x4C000004)))
#define TCFG0 (*((volatile unsigned long*)(0x51000000)))
#define TCFG1 (*((volatile unsigned long*)(0x51000004)))
#define TCNTB0 (*((volatile unsigned long*)(0x5100000C)))
#define TCON (*((volatile unsigned long*)(0x51000008)))
#define INTMSK (*((volatile unsigned long*)(0X4A000008)))
#define INTSUBMASK (*((volatile unsigned long*)(0X4A00001C)))
#define GPHCON (*((volatile unsigned long*)(0x56000070)))
#define GPHUP (*((volatile unsigned long*)(0x56000078)))
//control register of com0
#define ULCON0 (*((volatile unsigned long*)(0x50000000)))
#define UCON0 (*((volatile unsigned long*)(0x50000004)))
#define UFCON0 (*((volatile unsigned long*)(0x50000008)))
#define UMCON0 (*((volatile unsigned long*)(0x5000000C)))
#define UBRDIV0 (*((volatile unsigned long*)(0x50000028)))
//the control register of sckl, sdat (IIC)
#define GPECON (*((volatile unsigned long*)(0x56000040)))
#define GPEUP (*((volatile unsigned long*)(0x56000048)))
#define IICCON (*((volatile unsigned long*)(0x54000000)))
#define IICSTAT (*((volatile unsigned long*)(0x54000004)))
//initilize GPB to output mode
void init_led()
{
GPBCON &= (~(0xff<<10));
GPBCON |= (0X55<<10);
}
void delay(int times)
{
int i, j;
for(i=0; i for(j=0; j<1000; j++); } } //blink function is used to debug void blink(int number, int delay_num) { GPBDAT |= (0X0F<<5); GPBDAT &= (~(number<<5)); delay(delay_num); GPBDAT |= (0X0F<<5); delay(delay_num); } void disable_watchdog() { WTCON = 0; } void init_clock() { LOCKTIME = 0xffffffff; CLKDIVN = 0X03; //fclk:hclk:pclk=1:2:4 __asm__ ( "mrc p15, 0, r1, c1, c0, 0n" "orr r1, r1, #0xc0000000n" "mcr p15, 0, r1, c1, c0, 0n" ); MPLLCON = (92<<12)|(1<<4)|(2<<0); //fclk=200M, hclk=100M, pclk=50M } void init_sdram() { volatile unsigned long *p = (volatile unsigned long *)(0x48000000); p[0] = 0x22011110; //BWSCON p[1] = 0x00000700; //BANKCON0 p[2] = 0x00000700; //BANKCON1 p[3] = 0x00000700; //BANKCON2 p[4] = 0x00000700; //BANKCON3 p[5] = 0x00000700; //BANKCON4 p[6] = 0x00000700; //BANKCON5 p[7] = 0x00018005; //BANKCON6 p[8] = 0x00018005; //BANKCON7 p[9] = 0x008C04F4; //REFRESH value is different than before, because the clock is different p[10] = 0x000000B1; //BANKSIZE p[11] = 0x00000030; //MRSRB6 p[12] = 0x00000030; //MRSRB7 } void copy_sdram() { unsigned long* src = (unsigned long *)(0); unsigned long* des = (unsigned long *)(0x30000000); int i; for(i=0; i<1024; i++) { des[i] = src[i]; } } void init_irq() { //enable interrupt of rxd0 txd0 INTSUBMASK &= (~(0b11)); //enable interrupt of uart0 INTMSK &= (~(1<<28)); //enable IIC interrupt INTMSK &= (~(1<<27)); } //initialize the IIC bus void init_iic() { //set gpe[14:15] used for IIC GPECON &= (~(0b1111<<28)); GPECON |= (0b1010<<28); //enable the pulling up function GPEUP &= (~(0b11<<14)); /* 0b00100111 [7] disable ack signal [6] IICCLK=PCLK/16 [5] enable IIC rx interrupt and tx interrupt [4] clear IIC interrupt [3:0] tx clock = IICCLK/8 = 50000000/16/16 = 195.3125KHz */ IICCON = 0b00101111; //enable IIC R/T ability IICSTAT = 0x10; } void init_com0() { //set gph[2:3] used as txd and rxd for com0 GPHCON &= (~(0xff<<4)); GPHCON |= (0x0a<<4); //disable pull up functon for gph[2:3] GPHUP = 0x0c; //set properties of com0 ULCON0 = 0b00000011; //enable the rxd and txd, and interrupt will happen when con0 received data or the send buffer is empty in non-fifo mode UCON0 = 0b00000101; //disable fifo UFCON0 = 0x00; //disable fifo UMCON0 = 0x00; //set baud-rate to 115200 UBRDIV0 = (int)(50000000/(115200*16)) -1; } com0.c #define UTRSTAT0 (*((volatile unsigned long*)(0x50000010))) #define UTXH0 (*((volatile unsigned long*)(0x50000020))) #define URXH0 (*((volatile unsigned long*)(0x50000024))) #define SUBSRCPND (*((volatile unsigned long*)(0X4A000018))) #define SRCPND (*((volatile unsigned long*)(0X4A000000))) #define INTPND (*((volatile unsigned long*)(0X4A000010))) #define IICSTAT (*((volatile unsigned long*)(0x54000004))) #define IICDS (*((volatile unsigned long*)(0x5400000C))) extern void blink(int, int); extern unsigned char write_ack; extern unsigned char iic_mode; extern unsigned char read_over; extern unsigned char read_data; void put_char(char ch) { while (!(UTRSTAT0 & (1<<2))); UTXH0 = ch; } unsigned char get_char() { while (!(UTRSTAT0 & (1<<0))); return URXH0; } void put_string(char *string) { int i = 0; while(string[i] != '




