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