Skip to content

Commit 4199a73

Browse files
committed
Add firmware v1.13 patcher to examples.
1 parent 3acc72b commit 4199a73

File tree

2 files changed

+471
-0
lines changed

2 files changed

+471
-0
lines changed
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
// Adafruit CC3000 Firmware V1.13 Upgrade Sketch
2+
// Based on firmware patcher for MSP430 chips published by Texas Instruments.
3+
//
4+
// This sketch will upgrade CC3000 modules up to firmware version 1.13.
5+
//
6+
// You can find more details about the changes in the 1.13 firmware from TI at:
7+
// http://processors.wiki.ti.com/index.php/CC3000_Release_Notes
8+
//
9+
// In general the 1.13 release is a bug fix release with fixes for stability
10+
// issues that caused the CC3000 to hand when under load.
11+
//
12+
// WARNING: Upgrade firmware at your own risk! In general if the CC3000 is
13+
// currently working fine for your needs then hold off on the upgrade.
14+
//
15+
// Usage (read all the steps before strarting):
16+
// - Wire up your Arduino to the CC3000 just like you're running buildtest or
17+
// other examples.
18+
// - Adjust the ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_VBAT
19+
// defines below to match your wiring (just like running buildtest).
20+
// - Load the sketch on your Arduino and open the serial monitor at 115200 baud.
21+
// - You should see a prompt waiting for a key press to continue. Enter text
22+
// and press enter to start the upgrade.
23+
// - You will see text printed as the firmware is upgraded. The upgrade process
24+
// should be quick and take less than a minute.
25+
// - You might see a message at the end that the firmware version or MAC address
26+
// couldn't be read--this can be ignored.
27+
// - Once the firmware upgrade is complete, run the buildtest sketch to check
28+
// the CC3000 functionality.
29+
// - During the firmware upgrade the CC3000 MAC address might be lost. You can
30+
// write a new MAC address by uncommenting the appropriate line in the buildtest
31+
// example. Make sure to save your MAC address before upgrading the firmware
32+
// if you'd like to keep it the same after
33+
34+
#include <Adafruit_CC3000.h>
35+
#include <ccspi.h>
36+
#include <SPI.h>
37+
#include <string.h>
38+
#include <EEPROM.h>
39+
40+
#include "utility/debug.h"
41+
#include "utility/nvmem.h"
42+
#include "driverpatchinc_1_13.h"
43+
44+
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
45+
#define ADAFRUIT_CC3000_CS 10
46+
#define ADAFRUIT_CC3000_VBAT 5
47+
48+
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT);
49+
50+
/**************************************************************************/
51+
/*!
52+
@brief Displays the driver mode (tiny of normal), and the buffer
53+
size if tiny mode is not being used
54+
55+
@note The buffer size and driver mode are defined in cc3000_common.h
56+
*/
57+
/**************************************************************************/
58+
void displayDriverMode(void)
59+
{
60+
#ifdef CC3000_TINY_DRIVER
61+
Serial.println(F("CC3000 is configure in 'Tiny' mode"));
62+
#else
63+
Serial.print(F("RX Buffer : "));
64+
Serial.print(CC3000_RX_BUFFER_SIZE);
65+
Serial.println(F(" bytes"));
66+
Serial.print(F("TX Buffer : "));
67+
Serial.print(CC3000_TX_BUFFER_SIZE);
68+
Serial.println(F(" bytes"));
69+
#endif
70+
}
71+
72+
/**************************************************************************/
73+
/*!
74+
@brief Tries to read the CC3000's internal firmware patch ID
75+
*/
76+
/**************************************************************************/
77+
void displayFirmwareVersion(void)
78+
{
79+
#ifndef CC3000_TINY_DRIVER
80+
uint8_t major, minor;
81+
82+
if(!cc3000.getFirmwareVersion(&major, &minor))
83+
{
84+
Serial.println(F("Unable to retrieve the firmware version!\r\n"));
85+
}
86+
else
87+
{
88+
Serial.print(F("Firmware V. : "));
89+
Serial.print(major); Serial.print(F(".")); Serial.println(minor);
90+
}
91+
#endif
92+
}
93+
94+
/**************************************************************************/
95+
/*!
96+
@brief Tries to read the 6-byte MAC address of the CC3000 module
97+
*/
98+
/**************************************************************************/
99+
boolean MACvalid = false;
100+
// array to store MAC address from EEPROM
101+
uint8_t cMacFromEeprom[MAC_ADDR_LEN];
102+
void displayMACAddress(void)
103+
{
104+
if(!cc3000.getMacAddress(cMacFromEeprom))
105+
{
106+
Serial.println(F("Unable to retrieve MAC Address!\r\n"));
107+
MACvalid = false;
108+
}
109+
else
110+
{
111+
Serial.print(F("MAC Address : "));
112+
cc3000.printHex((byte*)&cMacFromEeprom, 6);
113+
MACvalid = true;
114+
}
115+
}
116+
117+
118+
119+
/**************************************************************************/
120+
/*!
121+
@brief Sets up the HW and the CC3000 module (called automatically
122+
on startup)
123+
*/
124+
/**************************************************************************/
125+
126+
uint8_t ucStatus_Dr, return_status = 0xFF;
127+
uint8_t counter = 0;
128+
129+
// array to store RM parameters from EEPROM
130+
unsigned char cRMParamsFromEeprom[128];
131+
132+
133+
// 2 dim array to store address and length of new FAT
134+
uint16_t aFATEntries[2][NVMEM_RM_FILEID + 1] =
135+
/* address */ {{0x50, 0x1f0, 0x1390, 0x0390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830},
136+
/* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200 }};
137+
/* 0. NVS */
138+
/* 1. NVS Shadow */
139+
/* 2. Wireless Conf */
140+
/* 3. Wireless Conf Shadow */
141+
/* 4. BT (WLAN driver) Patches */
142+
/* 5. WiLink (Firmware) Patches */
143+
/* 6. MAC addr */
144+
/* 7. Frontend Vars */
145+
/* 8. IP config */
146+
/* 9. IP config Shadow */
147+
/* 10. Bootloader Patches */
148+
/* 11. Radio Module params */
149+
/* 12. AES128 for smart config */
150+
/* 13. user file */
151+
/* 14. user file */
152+
/* 15. user file */
153+
154+
155+
void setup(void)
156+
{
157+
Serial.begin(115200);
158+
Serial.println(F("Hello, CC3000!\n"));
159+
160+
Serial.println(F("Hit any key & return to start"));
161+
while (!Serial.available());
162+
163+
pinMode(9, OUTPUT);
164+
pinMode(8, OUTPUT);
165+
pinMode(7, OUTPUT);
166+
pinMode(6, OUTPUT);
167+
digitalWrite(9, LOW);
168+
digitalWrite(8, LOW);
169+
digitalWrite(7, LOW);
170+
digitalWrite(6, LOW);
171+
172+
displayDriverMode();
173+
displayFreeRam();
174+
175+
/* Initialise the module */
176+
Serial.println(F("\nInitialising the CC3000 ..."));
177+
if (!cc3000.begin(2)) // init with NO patches!
178+
{
179+
Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
180+
while(1);
181+
}
182+
183+
displayFirmwareVersion();
184+
displayMACAddress();
185+
186+
return_status = 1;
187+
uint8_t index;
188+
uint8_t *pRMParams;
189+
190+
while ((return_status) && (counter < 3)) {
191+
// read RM parameters
192+
// read in 16 parts to work with tiny driver
193+
194+
return_status = 0;
195+
pRMParams = cRMParamsFromEeprom;
196+
197+
for (index = 0; index < 16; index++) {
198+
return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams);
199+
Serial.print(F("\n\rRead NVRAM $")); Serial.print(8*index); Serial.print("\t");
200+
for(uint8_t x=0; x<8; x++) {
201+
Serial.print("0x"); Serial.print(pRMParams[x], HEX); Serial.print(", ");
202+
}
203+
pRMParams += 8;
204+
}
205+
counter++;
206+
}
207+
// if RM file is not valid, load the default one
208+
if (counter == 3) {
209+
Serial.println(F("\n\rLoad default params"));
210+
pRMParams = (uint8_t *)cRMdefaultParams;
211+
} else {
212+
Serial.println(F("\n\rLoad EEPROM params"));
213+
pRMParams = cRMParamsFromEeprom;
214+
if (EEPROM.read(0) == 0xFF) {
215+
for (uint8_t e=0; e<128; e++) {
216+
EEPROM.write(e, cRMParamsFromEeprom[e]);
217+
}
218+
Serial.println(F("Backed up to eeprom!"));
219+
}
220+
}
221+
222+
223+
return_status = 1;
224+
225+
while (return_status) {
226+
// write new FAT
227+
return_status = fat_write_content(aFATEntries[0], aFATEntries[1]);
228+
Serial.print(F("Wrote FAT entries: ")); Serial.println(return_status, DEC);
229+
}
230+
231+
//Serial.println(F("Stopping..."));
232+
//cc3000.stop();
233+
234+
//Serial.println(F("\nInitialising the CC3000 ..."));
235+
236+
//if (!cc3000.begin(2)) // no patches!
237+
//{
238+
// Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
239+
// while(1);
240+
//}
241+
242+
return_status = 1;
243+
244+
Serial.println(F("Write params"));
245+
246+
while (return_status) {
247+
// write RM parameters
248+
// write in 4 parts to work with tiny driver
249+
250+
return_status = 0;
251+
252+
for (index = 0; index < 4; index++) {
253+
return_status |= nvmem_write(NVMEM_RM_FILEID, 32, 32*index, (pRMParams + 32*index));
254+
Serial.println(F("Wrote 32 bytes to NVRAM"));
255+
}
256+
}
257+
Serial.println(F("Wrote params"));
258+
259+
return_status = 1;
260+
261+
// write back the MAC address, only if exist
262+
if (MACvalid) {
263+
// zero out MCAST bit if set
264+
cMacFromEeprom[0] &= 0xfe;
265+
while (return_status) {
266+
return_status = nvmem_set_mac_address(cMacFromEeprom);
267+
}
268+
}
269+
270+
ucStatus_Dr = 1;
271+
Serial.println(F("Writing driver patch"));
272+
273+
while (ucStatus_Dr) {
274+
//writing driver patch to EEPRROM - PROTABLE CODE
275+
// Note that the array itself is changing between the different Service Packs
276+
ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, drv_length, wlan_drv_patch);
277+
}
278+
279+
280+
Serial.println(F("Wrote driver patch"));
281+
282+
Serial.println(F("Starting w/o patches"));
283+
284+
//if (!cc3000.begin(2))
285+
//{
286+
// Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
287+
// while(1);
288+
//}
289+
290+
Serial.println(F("Writing firmware"));
291+
292+
unsigned char ucStatus_FW = 1;
293+
294+
while (ucStatus_FW) {
295+
//writing FW patch to EAPRROM - PROTABLE CODE
296+
//Note that the array itself is changing between the different Service Packs
297+
ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, fw_length, fw_patch);
298+
}
299+
300+
Serial.println(F("Starting w/patches"));
301+
302+
if (!cc3000.begin(0))
303+
{
304+
Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
305+
while(1);
306+
}
307+
Serial.println(F("Patched!"));
308+
displayFirmwareVersion();
309+
displayMACAddress();
310+
}
311+
312+
313+
//*****************************************************************************
314+
//
315+
//! fat_write_content
316+
//!
317+
//! \param[in] file_address array of file address in FAT table:\n
318+
//! this is the absolute address of the file in the EEPROM.
319+
//! \param[in] file_length array of file length in FAT table:\n
320+
//! this is the upper limit of the file size in the EEPROM.
321+
//!
322+
//! \return on succes 0, error otherwise
323+
//!
324+
//! \brief parse the FAT table from eeprom
325+
//
326+
//*****************************************************************************
327+
uint8_t fat_write_content(uint16_t *file_address, uint16_t *file_length)
328+
{
329+
uint16_t index = 0;
330+
uint8_t ucStatus;
331+
uint8_t fatTable[48];
332+
uint8_t* fatTablePtr = fatTable;
333+
uint8_t LS[3] = "LS";
334+
335+
// first, write the magic number
336+
ucStatus = nvmem_write(16, 2, 0, LS);
337+
338+
for (; index <= NVMEM_RM_FILEID; index++)
339+
{
340+
// write address low char and mark as allocated
341+
*fatTablePtr++ = (uint8_t)(file_address[index] & 0xff) | _BV(0);
342+
343+
// write address high char
344+
*fatTablePtr++ = (uint8_t)((file_address[index]>>8) & 0xff);
345+
346+
// write length low char
347+
*fatTablePtr++ = (uint8_t)(file_length[index] & 0xff);
348+
349+
// write length high char
350+
*fatTablePtr++ = (uint8_t)((file_length[index]>>8) & 0xff);
351+
}
352+
353+
// second, write the FAT
354+
// write in two parts to work with tiny driver
355+
ucStatus = nvmem_write(16, 24, 4, fatTable);
356+
ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]);
357+
358+
// third, we want to erase any user files
359+
memset(fatTable, 0, sizeof(fatTable));
360+
ucStatus = nvmem_write(16, 16, 52, fatTable);
361+
362+
return ucStatus;
363+
}
364+
365+
366+
void loop(void)
367+
{
368+
delay(1000);
369+
}

0 commit comments

Comments
 (0)