]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/arch/arm/mach-lpc21xx/libs/iap/iap.c
Update of system-less architecture and board support code to actual uLAN.sf.net version.
[lincan.git] / embedded / arch / arm / mach-lpc21xx / libs / iap / iap.c
1 #include <system_def.h>
2 #include <cpu_def.h>
3 #include <hal_machperiph.h>
4
5 #define CMD_SUCCESS 0
6 #define BUSY 11
7
8 #define IAP_CMD_PREPARE         50
9 #define IAP_CMD_WRITE           51
10 #define IAP_CMD_ERASE           52
11 #define IAP_CMD_READ_PARTID     54
12
13 unsigned int command[5];
14 unsigned int result[2];
15
16 extern void iap_asm_entry (unsigned int *,unsigned int *);
17 #define iap_entry iap_asm_entry
18
19 #ifdef INC_LPC210x_H
20 inline int addr2sec(unsigned long addr)
21 {
22   return addr/0x2000;
23 }
24 #elif defined INC_LPC214x_H || defined INC_LPC2348_H
25 inline int addr2sec(unsigned long addr)
26 {
27   if (addr<0x8000) return (addr>>12);
28   else if (addr<0x78000) return (addr>>15)+7;
29        else return 22+((addr&0x7fff)>>12); 
30 }
31 #else
32 #error "Undefined type of CPU for function addr2sec!"
33 #endif
34
35 int lpcisp_read_partid() 
36 {
37   command[0] = IAP_CMD_READ_PARTID;
38   iap_entry(command, result);
39   return result[1];
40 }
41
42 int lpcisp_prepare_sectors(unsigned char start, unsigned char end)
43 {
44   command[0] = IAP_CMD_PREPARE;
45   command[1] = start;
46   command[2] = end;
47   command[3] = system_frequency/1000;
48
49   iap_entry(command, result);
50
51   return (CMD_SUCCESS == *result);
52 }
53
54 int lpcisp_erase_sectors(unsigned char start, unsigned char end)
55 {
56   command[0] = IAP_CMD_ERASE;
57   command[1] = start;
58   command[2] = end;
59   command[3] = system_frequency/1000;
60
61   iap_entry(command, result);
62
63   return (CMD_SUCCESS == *result);
64 }
65
66 int lpcisp_erase(void *addr, int len)
67 {
68   int start,end;
69   unsigned long flags;
70   
71   start=addr2sec((unsigned long)addr);
72   end=addr2sec((unsigned long)addr+len-1);
73   
74   if (end<start) return 0;
75
76   save_and_cli(flags);
77
78   lpcisp_prepare_sectors(start,end);
79   if (CMD_SUCCESS != *result) return 0;
80
81   lpcisp_erase_sectors(start,end);
82
83   restore_flags(flags);
84
85   return (CMD_SUCCESS == *result);
86 }
87
88 int lpcisp_write(void *addr_des, const void *addr_src, int len)
89 {
90   int start,end;
91   unsigned long flags;
92   
93   start=addr2sec((unsigned long)addr_des);
94   end=start;
95
96   save_and_cli(flags);
97
98   lpcisp_prepare_sectors(start,end);
99   if (CMD_SUCCESS != *result) return 0;
100
101   command[0] = IAP_CMD_WRITE;
102   command[1] = (unsigned int)addr_des;
103   command[2] = (unsigned int)addr_src;
104   command[3] = len;
105   command[4] = system_frequency/1000;
106
107   iap_entry(command, result);
108
109   restore_flags(flags);
110
111   return (CMD_SUCCESS == *result);
112 }
113
114