Test application for UV, IR, Light and Temperature sensors
[lpc82x] / core / rom_helpers.c
1 /****************************************************************************
2  *   core/rom_helpers.c
3  *
4  *
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *************************************************************************** */
21 /* ROM helpers are functions avalable for the user which do not use space in the
22  *  internal reprogrammable flash.
23  * They are stored in the internal ROM memory and may be called using specific
24  *  calls with defined parameters depending on the ROM call used.
25  * Refer to LPC82x documentation (UM10800.pdf) for more information.
26  */
28 #include "lib/stdint.h"
29 #include "core/system.h"
30 #include "core/iap.h"
31 #include "core/lpc_core.h"
33 /*******************************************************************************/
34 /*            Integer division using ROM based division routines               */
35 /*******************************************************************************/
37 struct idiv_return {
38         int quotient;
39         int remainder;
40 };
41 struct uidiv_return {
42         unsigned quotient;
43         unsigned remainder;
44 };
46 struct lpc_rom_div_helpers {
47         /* Signed integer division */
48         int (*rom_sidiv)(int numerator, int denominator);
49         /* Unsigned integer division */
50         unsigned (*rom_uidiv)(unsigned numerator, unsigned denominator);
51         /* Signed integer division with remainder */
52         struct idiv_return (*rom_sidivmod)(int numerator, int denominator);
53         /* Unsigned integer division with remainder */
54         struct uidiv_return (*rom_uidivmod)(unsigned numerator, unsigned denominator);
55 };
57 static struct lpc_rom_div_helpers* rom_div_helpers;
59 /* Division (/) */
60 int __aeabi_idiv(int numerator, int denominator)
61 {
62         return rom_div_helpers->rom_sidiv(numerator, denominator);
63 }
64 unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
65 {
66         return rom_div_helpers->rom_uidiv(numerator, denominator);
67 }
69 /* Modulo (%) */
70 void __aeabi_idivmod(int numerator, int denominator)
71 {
72         struct idiv_return result = rom_div_helpers->rom_sidivmod(numerator, denominator);
73         register uint32_t r0 asm("r0") = result.quotient;
74         register uint32_t r1 asm("r1") = result.remainder;
75         asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1));
76 }
77 void __aeabi_uidivmod(unsigned numerator, unsigned denominator)
78 {
79         struct uidiv_return result = rom_div_helpers->rom_uidivmod(numerator, denominator);
80         register uint32_t r0 asm("r0") = result.quotient;
81         register uint32_t r1 asm("r1") = result.remainder;
82         asm volatile("" : "+r"(r0), "+r"(r1) : "r"(r0), "r"(r1));
83 }
86 /*******************************************************************************/
87 /*            In Application Programming ROM based routines                    */
88 /*******************************************************************************/
91 enum iap_commands {
92         IAP_CMD_PREPARE_SECTORS_FOR_WRITE = 50,
93         IAP_CMD_COPY_RAM_TO_FLASH = 51,
94         IAP_CMD_ERASE_SECTORS = 52,
95         IAP_CMD_BLANK_CHECK_SECTORS = 53,
96         IAP_CMD_READ_PART_ID = 54,
97         IAP_CMD_READ_BOOT_CODE_VERSION = 55,
98         IAP_CMD_COMPARE = 56,
99         IAP_CMD_REINVOQUE_ISP = 57,
100         IAP_CMD_READ_UID = 58,
101         IAP_CMD_ERASE_PAGE = 59,
102 };
104 typedef void (*iap_entry_func)(uint32_t*, uint32_t*);
105 iap_entry_func iap_entry;
107 static uint32_t params[5];
108 static uint32_t results[4];
111 int iap_prepare_flash(uint32_t start_sector, uint32_t end_sector)
113         params[0] = IAP_CMD_PREPARE_SECTORS_FOR_WRITE;
114         params[1] = start_sector;
115         params[2] = end_sector;
116         iap_entry(params, results);
117         return results[0];
120 int iap_erase_flash_sectors(uint32_t start_sector, uint32_t end_sector)
122         params[0] = IAP_CMD_ERASE_SECTORS;
123         params[1] = start_sector;
124         params[2] = end_sector;
125         params[3] = (get_main_clock() / 1000);
126         lpc_disable_irq();
127         iap_entry(params, results);
128         lpc_enable_irq();
129         return results[0];
132 int iap_erase_flash_pages(uint32_t start_page, uint32_t end_page)
134         params[0] = IAP_CMD_ERASE_PAGE;
135         params[1] = start_page;
136         params[2] = end_page;
137         params[3] = (get_main_clock() / 1000);
138         lpc_disable_irq();
139         iap_entry(params, results);
140         lpc_enable_irq();
141         return results[0];
143 int iap_copy_ram_to_flash(uint32_t dest, uint32_t src, uint32_t size)
145         params[0] = IAP_CMD_COPY_RAM_TO_FLASH;
146         params[1] = dest & ~(0x03);
147         params[2] = src & ~(0x03);
148         params[3] = size & ~(0x03);
149         params[4] = (get_main_clock() / 1000);
150         lpc_disable_irq();
151         iap_entry(params, results);
152         lpc_enable_irq();
153         return results[0];
156 uint32_t iap_read_part_id(void)
158         params[0] = IAP_CMD_READ_PART_ID;
159         iap_entry(params, results);
160         return results[1];
164 /*******************************************************************************/
165 /*            Rom based routines initialisation                                */
166 /*******************************************************************************/
167 #define LPC_82x_ROM_HELPERS (0x1FFF1FF8)
168 #define LPC_82x_IAP_ROM_LOC (0x1FFF1FF1)
170 struct rom_helpers {
171     const unsigned p_dev0;
172     const unsigned p_dev1;
173     const unsigned p_dev2;
174     const unsigned rom_power_profiles;
175     const unsigned rom_div;
176     const unsigned rom_i2c_driver;
177     const unsigned p_dev6;
178     const unsigned rom_spi_driver;
179     const unsigned rom_adc_driver;
180     const unsigned rom_usart_driver;
181     const unsigned p_dev10;
182 };
183 #define ROM_DRIVERS ((struct rom_helpers *)(*((uint32_t *)LPC_82x_ROM_HELPERS)))
185 void rom_helpers_init(void)
187         rom_div_helpers = (struct lpc_rom_div_helpers*)(ROM_DRIVERS->rom_div);
188         iap_entry = (iap_entry_func)LPC_82x_IAP_ROM_LOC;