summaryrefslogtreecommitdiffstatshomepage
path: root/drivers/cc3000/src/patch_prog.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-09-26 00:56:45 +0100
committerDamien George <damien.p.george@gmail.com>2014-09-26 00:56:45 +0100
commitf996d8854f0cdd88446a8a369e1b330c14ea3eb7 (patch)
tree3cd5949d155bc412e4b28b8c47bb9cd19e51fd0c /drivers/cc3000/src/patch_prog.c
parent55a5b807937a4be8d57153970d723bc31113b6d4 (diff)
downloadmicropython-f996d8854f0cdd88446a8a369e1b330c14ea3eb7.tar.gz
micropython-f996d8854f0cdd88446a8a369e1b330c14ea3eb7.zip
drivers, cc3k: Move cc3000 driver from stmhal to drivers directory.
Diffstat (limited to 'drivers/cc3000/src/patch_prog.c')
-rw-r--r--drivers/cc3000/src/patch_prog.c414
1 files changed, 414 insertions, 0 deletions
diff --git a/drivers/cc3000/src/patch_prog.c b/drivers/cc3000/src/patch_prog.c
new file mode 100644
index 0000000000..fd128928fb
--- /dev/null
+++ b/drivers/cc3000/src/patch_prog.c
@@ -0,0 +1,414 @@
+#include <stdio.h>
+#include <string.h>
+#include "cc3000_common.h"
+#include "nvmem.h"
+#include "ccspi.h"
+#include "hci.h"
+#include "wlan.h"
+#include "patch_prog.h"
+#define BIT0 0x1
+#define BIT1 0x2
+#define BIT2 0x4
+#define BIT3 0x8
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+static unsigned char ucStatus_Dr;
+static unsigned char ucStatus_FW;
+static unsigned char return_status = 0xFF;
+
+static signed char mac_status = -1;
+static unsigned char counter = 0;
+
+// Array to store RM parameters from EEPROM.
+static unsigned char cRMParamsFromEeprom[128];
+// Array to store MAC address from EEPROM.
+static unsigned char cMacFromEeprom[MAC_ADDR_LEN];
+// Smart Config Prefix
+static const char aucCC3000_prefix[] = {'T', 'T', 'T'};
+
+static void systick_sleep(unsigned long ms) {
+ extern void HAL_Delay(volatile uint32_t Delay);
+ HAL_Delay(ms);
+}
+
+// 2 dim array to store address and length of new FAT
+static const unsigned short aFATEntries[2][NVMEM_RM_FILEID + 1] =
+/* address */ {{0x50, 0x1f0, 0x390, 0x1390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830},
+/* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200}};
+/* 0. NVS */
+/* 1. NVS Shadow */
+/* 2. Wireless Conf */
+/* 3. Wireless Conf Shadow */
+/* 4. BT (WLAN driver) Patches */
+/* 5. WiLink (Firmware) Patches */
+/* 6. MAC addr */
+/* 7. Frontend Vars */
+/* 8. IP config */
+/* 9. IP config Shadow */
+/* 10. Bootloader Patches */
+/* 11. Radio Module params */
+/* 12. AES128 for smart config */
+/* 13. user file */
+/* 14. user file */
+/* 15. user file */
+
+//*****************************************************************************
+//
+//! sendDriverPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the driver patch:
+//! since there is no patch yet - it returns 0
+//
+//*****************************************************************************
+
+static char *sendDriverPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+
+//*****************************************************************************
+//
+//! sendBootLoaderPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the boot loader patch:
+//! since there is no patch yet - it returns 0
+//
+//*****************************************************************************
+
+static char *sendBootLoaderPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+//*****************************************************************************
+//
+//! sendWLFWPatch
+//!
+//! \param pointer to the length
+//!
+//! \return none
+//!
+//! \brief The function returns a pointer to the FW patch:
+//! since there is no patch yet - it returns 0
+//
+//*****************************************************************************
+
+static char *sendWLFWPatch(unsigned long *Length)
+{
+ *Length = 0;
+ return NULL;
+}
+
+//*****************************************************************************
+//
+//! CC3000_UsynchCallback
+//!
+//! \param Event type
+//!
+//! \return none
+//!
+//! \brief The function handles asynchronous events that come from CC3000
+//! device and operates a LED4 to have an on-board indication
+//
+//*****************************************************************************
+
+static void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
+{
+
+}
+
+//*****************************************************************************
+//
+//! initDriver
+//!
+//! \param[in] cRequestPatch 0 to load with EEPROM patches
+//! and 1 to load with no patches
+//!
+//! \return none
+//!
+//! \brief The function initializes a CC3000 device
+//! and triggers it to start operation
+//
+//*****************************************************************************
+static int initDriver(unsigned short cRequestPatch)
+{
+ // WLAN On API Implementation
+ wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch,
+ ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin);
+
+ // Trigger a WLAN device
+ wlan_start(cRequestPatch);
+ wlan_smart_config_set_prefix((char*)aucCC3000_prefix);
+ wlan_ioctl_set_connection_policy(0, 0, 0);
+ wlan_ioctl_del_profile(255);
+
+ // Mask out all non-required events from CC3000
+ wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|
+ HCI_EVNT_WLAN_UNSOL_INIT|
+ HCI_EVNT_WLAN_ASYNC_PING_REPORT);
+
+ //unsolicicted_events_timer_init();
+ systick_sleep(100);
+ return(0);
+}
+
+
+//*****************************************************************************
+//
+//! fat_read_content
+//!
+//! \param[out] is_allocated array of is_allocated in FAT table:\n
+//! an allocated entry implies the address and length of the
+//! file are valid.
+//! 0: not allocated; 1: allocated.
+//! \param[out] is_valid array of is_valid in FAT table:\n
+//! a valid entry implies the content of the file is relevant.
+//! 0: not valid; 1: valid.
+//! \param[out] write_protected array of write_protected in FAT table:\n
+//! a write protected entry implies it is not possible to write
+//! into this entry.
+//! 0: not protected; 1: protected.
+//! \param[out] file_address array of file address in FAT table:\n
+//! this is the absolute address of the file in the EEPROM.
+//! \param[out] file_length array of file length in FAT table:\n
+//! this is the upper limit of the file size in the EEPROM.
+//!
+//! \return on succes 0, error otherwise
+//!
+//! \brief parse the FAT table from eeprom
+//
+//*****************************************************************************
+static unsigned char __attribute__ ((unused))
+fat_read_content(unsigned char *is_allocated, unsigned char *is_valid,
+ unsigned char *write_protected, unsigned short *file_address, unsigned short *file_length)
+{
+ unsigned short index;
+ unsigned char ucStatus;
+ unsigned char fatTable[48];
+ unsigned char* fatTablePtr = fatTable;
+
+ //
+ // Read in 6 parts to work with tiny driver
+ //
+ for (index = 0; index < 6; index++)
+ {
+ ucStatus = nvmem_read(16, 8, 4 + 8*index, fatTablePtr);
+ fatTablePtr += 8;
+ }
+
+ fatTablePtr = fatTable;
+
+ for (index = 0; index <= NVMEM_RM_FILEID; index++)
+ {
+ *is_allocated++ = (*fatTablePtr) & BIT0;
+ *is_valid++ = ((*fatTablePtr) & BIT1) >> 1;
+ *write_protected++ = ((*fatTablePtr) & BIT2) >> 2;
+ *file_address++ = ((*(fatTablePtr+1)<<8) | (*fatTablePtr)) & (BIT4|BIT5|BIT6|BIT7);
+ *file_length++ = ((*(fatTablePtr+3)<<8) | (*(fatTablePtr+2))) & (BIT4|BIT5|BIT6|BIT7);
+
+ //
+ // Move to next file ID
+ //
+ fatTablePtr += 4;
+ }
+
+ return ucStatus;
+}
+
+//*****************************************************************************
+//
+//! fat_write_content
+//!
+//! \param[in] file_address array of file address in FAT table:\n
+//! this is the absolute address of the file in the EEPROM.
+//! \param[in] file_length array of file length in FAT table:\n
+//! this is the upper limit of the file size in the EEPROM.
+//!
+//! \return on succes 0, error otherwise
+//!
+//! \brief parse the FAT table from eeprom
+//
+//*****************************************************************************
+static unsigned char fat_write_content(unsigned short const *file_address,
+ unsigned short const *file_length)
+{
+ unsigned short index = 0;
+ unsigned char ucStatus;
+ unsigned char fatTable[48];
+ unsigned char* fatTablePtr = fatTable;
+
+ //
+ // First, write the magic number.
+ //
+ ucStatus = nvmem_write(16, 2, 0, (unsigned char*)"LS");
+
+ for (; index <= NVMEM_RM_FILEID; index++)
+ {
+ //
+ // Write address low char and mark as allocated.
+ //
+ *fatTablePtr++ = (unsigned char)(file_address[index] & 0xff) | BIT0;
+
+ //
+ // Write address high char.
+ //
+ *fatTablePtr++ = (unsigned char)((file_address[index]>>8) & 0xff);
+
+ //
+ // Write length low char.
+ //
+ *fatTablePtr++ = (unsigned char)(file_length[index] & 0xff);
+
+ //
+ // Write length high char.
+ //
+ *fatTablePtr++ = (unsigned char)((file_length[index]>>8) & 0xff);
+ }
+
+ //
+ // Second, write the FAT.
+ // Write in two parts to work with tiny driver.
+ //
+ ucStatus = nvmem_write(16, 24, 4, fatTable);
+ ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]);
+
+ //
+ // Third, we want to erase any user files.
+ //
+ memset(fatTable, 0, sizeof(fatTable));
+ ucStatus = nvmem_write(16, 16, 52, fatTable);
+
+ return ucStatus;
+}
+
+void patch_prog_start()
+{
+ unsigned short index;
+ unsigned char *pRMParams;
+
+ printf("Initializing module...\n");
+
+ // Init module and request to load with no patches.
+ // This is in order to overwrite restrictions to
+ // write to specific places in EEPROM.
+ initDriver(1);
+
+ // Read MAC address.
+ mac_status = nvmem_get_mac_address(cMacFromEeprom);
+
+ return_status = 1;
+
+ printf("Reading RM parameters...\n");
+ while ((return_status) && (counter < 3)) {
+ // Read RM parameters.
+ // Read in 16 parts to work with tiny driver.
+ return_status = 0;
+ pRMParams = cRMParamsFromEeprom;
+ for (index = 0; index < 16; index++) {
+ return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams);
+ pRMParams += 8;
+ }
+ counter++;
+ }
+
+ // If RM file is not valid, load the default one.
+ if (counter == 3) {
+ printf("RM is not valid, loading default one...\n");
+ pRMParams = (unsigned char *)cRMdefaultParams;
+ } else {
+ printf("RM is valid.\n");
+ pRMParams = cRMParamsFromEeprom;
+ }
+
+ return_status = 1;
+
+ printf("Writing new FAT\n");
+ while (return_status) {
+ // Write new FAT.
+ return_status = fat_write_content(aFATEntries[0], aFATEntries[1]);
+ }
+
+ return_status = 1;
+
+ printf("Writing RM parameters...\n");
+ while (return_status) {
+ // Write RM parameters.
+ // Write in 4 parts to work with tiny driver.
+ return_status = 0;
+
+ for (index = 0; index < 4; index++) {
+ return_status |= nvmem_write(NVMEM_RM_FILEID,
+ 32,
+ 32*index,
+ (pRMParams + 32*index));
+ }
+ }
+
+ return_status = 1;
+
+ // Write back the MAC address, only if exists.
+ if (mac_status == 0) {
+ // Zero out MCAST bit if set.
+ cMacFromEeprom[0] &= 0xfe;
+ printf("Writing back MAC address..\n");
+ while (return_status) {
+ return_status = nvmem_set_mac_address(cMacFromEeprom);
+ }
+ }
+
+ // Update driver
+ ucStatus_Dr = 1;
+ printf("Updating driver patch...\n");
+ while (ucStatus_Dr) {
+ // Writing driver patch to EEPRROM - PROTABLE CODE
+ // Note that the array itself is changing between the
+ // different Service Packs.
+ ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID,
+ drv_length,
+ wlan_drv_patch);
+ }
+
+ // Update firmware
+ ucStatus_FW = 1;
+ printf("Updating firmware patch...\n");
+ while (ucStatus_FW) {
+ // Writing FW patch to EEPRROM - PROTABLE CODE
+ // Note that the array itself is changing between the
+ // different Service Packs.
+ ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID,
+ fw_length,
+ fw_patch);
+ }
+
+ printf("Update complete, resetting module\n"\
+ "If this doesn't work, reset manually...\n");
+
+ wlan_stop();
+ systick_sleep(500);
+
+ // Re-Init module and request to load with patches.
+ initDriver(0);
+
+ // If MAC does not exist, it is recommended
+ // that the user will write a valid mac address.
+ if (mac_status != 0) {
+ printf("MAC address is not valid, please write a new one\n");
+ }
+
+ // Patch update done
+ printf("All done, call wlan.patch_version()\n");
+}