]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/arch/arm/mach-lpc21xx/libs/iap/iap.c
Included ARM LPC21xx related code from uLan project. The snapshot date is 2008-07-05
[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 uint32_t command[5];
14 uint32_t 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
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] = FOSC/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] = FOSC/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   lpc_pll_off();
78
79   lpcisp_prepare_sectors(start,end);
80   if (CMD_SUCCESS != *result) return 0;
81
82   lpcisp_erase_sectors(start,end);
83
84   lpc_pll_on();
85   restore_flags(flags);
86
87   return (CMD_SUCCESS == *result);
88 }
89
90 int lpcisp_write(void *addr_des, const void *addr_src, int len)
91 {
92   int start,end;
93   unsigned long flags;
94   
95   start=addr2sec((unsigned long)addr_des);
96   end=start;
97
98   save_and_cli(flags);
99   lpc_pll_off();
100
101   lpcisp_prepare_sectors(start,end);
102   if (CMD_SUCCESS != *result) return 0;
103
104   command[0] = IAP_CMD_WRITE;
105   command[1] = (unsigned int)addr_des;
106   command[2] = (unsigned int)addr_src;
107   command[3] = len;
108   command[4] = FOSC/1000;
109
110   iap_entry(command, result);
111
112   lpc_pll_on();
113   restore_flags(flags);
114
115   return (CMD_SUCCESS == *result);
116 }
117
118