]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/arch/arm/mach-lpc17xx/libs/iap/iap.c
Contributed support for LCP17xx devices and PiKRON's LMC1 board.
[lincan.git] / embedded / arch / arm / mach-lpc17xx / 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[5];
15
16 #define IAP_LOCATION 0x1FFF1FF1
17
18 typedef void (*IAP)(unsigned int [],unsigned int[]);
19 IAP iap_entry = (IAP) IAP_LOCATION;
20
21 static inline int addr2sec(unsigned long addr)
22 {
23   if (addr<0x10000) {
24     return (addr>>12);
25   } else {
26     addr-=0x10000;
27     return (addr>>15)+16;
28   }
29 }
30
31 int lpcisp_read_partid() 
32 {
33   command[0] = IAP_CMD_READ_PARTID;
34   iap_entry(command, result);
35   return result[1];
36 }
37
38 int lpcisp_prepare_sectors(unsigned char start, unsigned char end)
39 {
40   command[0] = IAP_CMD_PREPARE;
41   command[1] = start;
42   command[2] = end;
43
44   iap_entry(command, result);
45
46   return (CMD_SUCCESS == *result);
47 }
48
49 int lpcisp_erase_sectors(unsigned char start, unsigned char end)
50 {
51   command[0] = IAP_CMD_ERASE;
52   command[1] = start;
53   command[2] = end;
54   command[3] = system_frequency/1000;
55
56   iap_entry(command, result);
57
58   return (CMD_SUCCESS == *result);
59 }
60
61 int lpcisp_erase(void *addr, int len)
62 {
63   int start,end;
64   unsigned long flags;
65   
66   start=addr2sec((unsigned long)addr);
67   end=addr2sec((unsigned long)addr+len-1);
68   
69   if (end<start) return 0;
70
71   save_and_cli(flags);
72
73   lpcisp_prepare_sectors(start,end);
74   if (CMD_SUCCESS != *result) return 0;
75
76   lpcisp_erase_sectors(start,end);
77
78   restore_flags(flags);
79
80   return (CMD_SUCCESS == *result);
81 }
82
83 int lpcisp_write(void *addr_des, const void *addr_src, int len)
84 {
85   int start,end;
86   unsigned long flags;
87   
88   start=addr2sec((unsigned long)addr_des);
89   end=start;
90
91   save_and_cli(flags);
92
93   lpcisp_prepare_sectors(start,end);
94   if (CMD_SUCCESS != *result) return 0;
95
96   command[0] = IAP_CMD_WRITE;
97   command[1] = (unsigned int)addr_des;
98   command[2] = (unsigned int)addr_src;
99   command[3] = len;
100   command[4] = system_frequency/1000;
101
102   iap_entry(command, result);
103
104   restore_flags(flags);
105
106   return (CMD_SUCCESS == *result);
107 }
108
109