This commit is contained in:
rusefi 2019-06-06 20:12:03 -04:00
parent 97a557a57e
commit c031252c75
4 changed files with 361 additions and 32 deletions

View File

@ -25,6 +25,8 @@
EXTERN_CONFIG;
static OutputPin chipSelect;
static OutputPin resetB;
static OutputPin driven;
static SPIConfig spiCfg = { .circular = false,
.end_cb = NULL,
@ -34,8 +36,8 @@ static SPIConfig spiCfg = { .circular = false,
SPI_CR1_16BIT_MODE |
SPI_CR1_MSTR |
//SPI_CR1_BR_1 // 5MHz
SPI_CR1_CPHA | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2,
.cr2 = 0};
SPI_CR1_CPHA | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 | SPI_CR1_SPE,
.cr2 = SPI_CR2_SSOE};
static SPIDriver *driver;
@ -44,15 +46,219 @@ static void showStats() {
}
static void send_16bit_SPI(short param) {
spiSelect(driver);
// we are in 16 bit mode so '1' means 16 bits word hopefully?
// Mostly unused
unsigned short recv_16bit_spi() {
unsigned short ret;
//spiSelect(driver);
spiReceive(driver, 1, &ret);
//spiUnselect(driver);
return ret;
}
// This could be used to detect if check byte is wrong.. or use a FLAG after init
unsigned short txrx_16bit_spi(const unsigned short param) {
unsigned short ret;
//spiSelect(driver);
spiExchange(driver, 1, &param, &ret);
//spiUnselect(driver);
return ret;
}
// Send 16bits
static void spi_writew(unsigned short param) {
//spiSelect(driver);
spiSend(driver, 1, &param);
//spiUnselect(driver);
}
static unsigned short id() {
spiSelect(driver);
spi_writew(0xBAA1);
unsigned short ID = recv_16bit_spi();
spiUnselect(driver);
return ID;
}
static void setup_spi() {
spiSelect(driver);
// Select Channel command
spi_writew(0x7FE1);
// Common Page
spi_writew(0x0004);
// Configure SPI command
spi_writew(0x3901);
// Mode A + Watchdog timer full
//spi_writew(0x001F);
spi_writew(0x009F); // + fast slew rate on miso
spiUnselect(driver);
}
static void sentWord(int word) {
send_16bit_SPI(word);
static void enable_flash()
{
spiSelect(driver);
spi_writew(0x2001); //ch1
spi_writew(0x0018); //enable flash
spi_writew(0x2401); //ch2
spi_writew(0x0018); // enable flash
spiUnselect(driver);
}
static void download_RAM(int target) {
unsigned short memory_area = 0; // memory area
unsigned short start_address = 0; // start address
unsigned short codeWidthRegAddr = 0; // code width register address
unsigned short size = 0; // size of RAM data
unsigned short command = 0; // command data
unsigned short data = 0; // RAM data
unsigned int k = 0; // used in loop for writing RAM data to the chip
const unsigned short *RAM_ptr; // pointer to array of data to be sent to the chip
//Why Again? For Every time, just in case?
setup_spi();
switch(target) // selects target
{
case CODE_RAM1:
memory_area = 0x1;
start_address = 0;
codeWidthRegAddr = 0x107;
RAM_ptr = MC33816_code_RAM1;
size = sizeof(MC33816_code_RAM1) / 2;
break;
case CODE_RAM2:
memory_area = 0x2;
start_address = 0;
codeWidthRegAddr = 0x127;
RAM_ptr = MC33816_code_RAM2;
size = sizeof(MC33816_code_RAM2) / 2;
break;
case DATA_RAM: // ch1 only?
memory_area = 0x4;
start_address = 0;
RAM_ptr = MC33816_data_RAM;
size = sizeof(MC33816_data_RAM) / 2;
break;
// optional, both data_rams with 0x3, writes same code to both
default:
break;
}
// Chip-Select high
spiSelect(driver);
if (target != DATA_RAM)
{
command = codeWidthRegAddr << 5; // control width register address
command |= 1; // number of words to follow
spi_writew(command); // sends code_width command
spi_writew(size); // sends size (Code Width)
}
// Select Channel command
spi_writew(0x7FE1);
// RAM1, RAM2, or Common Page (Data RAM)
spi_writew(memory_area);
// "Command" of starting address
// up to 0x03FE of code ram
// up to 0x0080 of data ram
command = start_address << 5;
spi_writew(command); // sends start address command
/*
for(k = 0; k < size; k++) // downloads RAM
{
data = *RAM_ptr; // retrieves data to be sent
spi_writew(data); // sends data
RAM_ptr++;
}
*/
spiSend(driver, size, RAM_ptr);
spiUnselect(driver);
}
static void download_register(int r_target) {
unsigned short r_start_address = 0; // start address
unsigned short r_size = 0; // size of configuration data
unsigned short r_command = 0; // command data
unsigned short r_data = 0; // configuration data
int n = 0; // used for loop for writing data to the chip
unsigned short remainder_size = 0; // remainder size
const unsigned short *reg_ptr; // pointer to array of data to be sent to the chip
switch(r_target) // selects target
{
case REG_CH1: // channel 1 configurations
r_start_address = 0x100;
reg_ptr = MC33816_ch1_config;
r_size = sizeof(MC33816_ch1_config) / 2; // gets number of words to be sent
break;
case REG_CH2: // channel 2 configurations
r_start_address = 0x120;
reg_ptr = MC33816_ch2_config;
r_size = sizeof(MC33816_ch2_config) / 2; // gets number of words to be sent
break;
case REG_DIAG: // diagnostic configurations
r_start_address = 0x140;
reg_ptr = MC33816_diag_config;
r_size = sizeof(MC33816_diag_config) / 2; // gets number of words to be sent
break;
case REG_IO: // IO configurations
r_start_address = 0x180;
reg_ptr = MC33816_io_config;
r_size = sizeof(MC33816_io_config) / 2; // gets number of words to be sent
break;
case REG_MAIN: // main configurations
r_start_address = 0x1C0;
reg_ptr = MC33816_main_config;
r_size = sizeof(MC33816_main_config) / 2; // gets number of words to be sent
break;
default:
break;
}
//for location < size(remainder?)
// is location == 0? or past max xfer, send command + expected size
// if location = max xfer
//
// retrieve data, send it, increase pointer
// increase
if(r_size > MAX_SPI_MODE_A_TRANSFER_SIZE) //if size is too large, split into two sections ... MULTIPLE sections..
{
remainder_size = r_size - MAX_SPI_MODE_A_TRANSFER_SIZE; // creates remaining size
r_size = MAX_SPI_MODE_A_TRANSFER_SIZE; // sets first size
}
r_command = r_start_address << 5; // start address
r_command += r_size; // number of words to follow
spiSelect(driver); // Chip
spi_writew(r_command); // sends address and number of words to be sent
spiSend(driver, r_size, reg_ptr);
if(remainder_size > 0) // if remainder size is greater than 0, download the rest
{
r_start_address += r_size; // new start address
r_command = r_start_address << 5; // start address
r_command += remainder_size; // number of words to follow
spi_writew(r_command); // sends address and number of words to be sent
spiSend(driver, remainder_size, reg_ptr + r_size);
}
spiUnselect(driver);
}
void initMc33816() {
@ -61,12 +267,18 @@ void initMc33816() {
// default spi3sckPin PB3
// ideally disable isSdCardEnabled since it's on SPI3
// uncomment thid to hard-code something
//CONFIG(mc33816_cs) = GPIOD_7;
// uncomment this to hard-code something
CONFIG(mc33816_cs) = GPIOD_7;
CONFIG(mc33816_rstb) = GPIOD_5;
CONFIG(mc33816_driven) = GPIOD_6;
// and more to add...
if (CONFIG(mc33816_cs) == GPIO_UNASSIGNED)
return;
// Initialize the chip via ResetB
resetB.initPin("mc33 RESTB", engineConfiguration->mc33816_rstb);
chipSelect.initPin("mc33 CS", engineConfiguration->mc33816_cs /*, &engineConfiguration->csPinMode*/);
spiCfg.ssport = getHwPort("hip", CONFIG(mc33816_cs));
@ -83,21 +295,49 @@ void initMc33816() {
spiStart(driver, &spiCfg);
addConsoleAction("mc33_stats", showStats);
//addConsoleAction("mc33_stats", showStats);
//addConsoleActionI("mc33_send", sendWord);
addConsoleActionI("mc33_send", sentWord);
// Does starting turn this high to begin with??
spiUnselect(driver);
int size = 105;
//delay/wait? .. possibly only 30us for each needed, per datasheet
resetB.setValue(0);
chThdSleepMilliseconds(10);
resetB.setValue(1);
chThdSleepMilliseconds(10);
unsigned short * RAM_ptr = MC33816_code_RAM1;
setup_spi();
int mc_id = id();
for (int k = 0; k < size; k++) // downloads RAM
{
short data = *RAM_ptr; // retrieves data to be sent
send_16bit_SPI(data); // sends data
RAM_ptr++;
}
download_RAM(CODE_RAM1); // transfers code RAM1
download_RAM(CODE_RAM2); // transfers code RAM2
download_RAM(DATA_RAM); // transfers data RAM
download_register(REG_MAIN); // download main register configurations
download_register(REG_CH1); // download channel 1 register configurations
download_register(REG_CH2); // download channel 2 register configurations
download_register(REG_IO); // download IO register configurations
download_register(REG_DIAG); // download diag register configuration
enable_flash();
//driven.setValue(1); // driven = HV
}
void update_scv(unsigned short current)
{
// Update a single word in Data RAM
spiSelect(driver);
// Select Channel command
spi_writew(0x7FE1);
// Common Page
spi_writew(0x0004);
// write (MSB=0) at data ram x9 (SCV_I_Hold), and 1 word
spi_writew((9 << 5) + 1);
spi_writew(current);
spiUnselect(driver);
// Strobe it to reload the value
//GPIO_ClearPinsOutput(GPIOE, 1<<PIN21_IDX); // SCV
//GPIO_SetPinsOutput(GPIOE, 1<<PIN21_IDX); // SCV
}

View File

@ -8,6 +8,21 @@
#ifndef HW_LAYER_MC33816_H_
#define HW_LAYER_MC33816_H_
const int MAX_SPI_MODE_A_TRANSFER_SIZE = 31; //max size for register config transfer
enum {
CODE_RAM1,
CODE_RAM2,
DATA_RAM
};
enum {
REG_MAIN,
REG_CH1,
REG_CH2,
REG_IO,
REG_DIAG
};
void initMc33816(void);
#endif /* HW_LAYER_MC33816_H_ */

View File

@ -3,18 +3,85 @@
*
*/
unsigned short MC33816_code_RAM1[105] =
// Data to be loaded into the Code RAM 1 memory space
const unsigned short MC33816_code_RAM1[62] =
{
0x3629, 0x0185, 0x41F9, 0xB169, 0xF64B, 0xA77C, 0x3142, 0x028C, 0xBD43, 0x1E99,
0xC958, 0xD52F, 0xB562, 0x27CA, 0xD617, 0xA63C, 0x2596, 0xE00F, 0xB8F9, 0xF657,
0x9FB7, 0x2ACF, 0x8A60, 0x24C0, 0x7914, 0x2CED, 0x71BF, 0x5B3A, 0x0604, 0x3605,
0x3BA8, 0x7362, 0x88EA, 0xF613, 0xD6DD, 0xB055, 0xD629, 0x32C2, 0x2375, 0xE08B,
0xFA18, 0xEBC5, 0xAA8F, 0x5EAA, 0x3987, 0x106C, 0xE468, 0x64A1, 0x0FB0, 0x7879,
0x9664, 0xA0D8, 0x7AE7, 0x1512, 0x829E, 0xBB5D, 0x03FC, 0x7228, 0xE94B, 0xF458,
0x1E33, 0x83B0, 0xCE2D, 0xF930, 0xF458, 0x1F33, 0x9A9C, 0x8A34, 0x31AE, 0x6853,
0x359C, 0xAF20, 0xBA3A, 0x9E1A, 0x2F68, 0x72F5, 0x0491, 0x96FF, 0x28B8, 0xE434,
0xA72A, 0xFA05, 0x7481, 0x9721, 0x1392, 0x2167, 0x4AF1, 0xC959, 0x3A6A, 0xB248,
0xAB35, 0x094F, 0xAF6F, 0x8DFA, 0x0BA7, 0x0B26, 0x978C, 0xD0E1, 0xCDC5, 0x34C6,
0x18F8, 0x3E6C, 0x4186, 0xB14B, 0xDB33
0x96A3, 0x19F0, 0x520A, 0x4368, 0x173F, 0x200B, 0x70F0, 0x8233, 0xF82E, 0x7DEB,
0x8D45, 0xC517, 0xBFEE, 0xE825, 0x8A53, 0xDE14, 0xFE66, 0xB2B6, 0x5361, 0xD258,
0x8D93, 0x9C83, 0x8078, 0xB95D, 0x2831, 0x8050, 0xE191, 0x16C1, 0x806F, 0x193F,
0x9E9C, 0x3B7E, 0x5D3B, 0xB58F, 0x156F, 0x82E8, 0x8277, 0x5F3F, 0x2F78, 0xE440,
0x7C77, 0x2ABF, 0x5000, 0x121A, 0x16C8, 0x2B7C, 0x90A2, 0x0897, 0xA640, 0x49E5,
0xF5D5, 0xDA94, 0xF590, 0xBF10, 0xA88F, 0xDACA, 0x37E7, 0x42A9, 0xF5B0, 0x22AD,
0xAF73, 0xD332
};
// Data to be loaded into the Code RAM 2 memory space
const unsigned short MC33816_code_RAM2[43] =
{
0x96AA, 0x1A9E, 0x40F8, 0x66C8, 0xC91C, 0xEC3E, 0x83E5, 0x8286, 0xE3DC, 0xC8F3,
0x9741, 0xC437, 0x4371, 0xE987, 0x8B0A, 0xDE55, 0x9A83, 0x0785, 0x811C, 0x3BED,
0x7050, 0x28D7, 0x247E, 0x9C72, 0x5470, 0x8DA3, 0x4625, 0x4945, 0x31F0, 0x1BA9,
0x9FFD, 0x5E7A, 0x8FF1, 0xE325, 0x1FAE, 0x80B7, 0x70E5, 0x5E5C, 0x4A35, 0x8651,
0x7C77, 0x2ABE, 0x5D5D
};
// Data to be loaded into the Data RAM memory space
const unsigned short MC33816_data_RAM[128] =
{
0x00F0, 0x00F0, 0x008C, 0x003C, 0x04B0, 0x00B4, 0x003C, 0xEA60, 0x0000, 0x003D,
0x6000, 0x003C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x00C1, 0x00BF, 0x002F, 0x001D, 0x0000, 0x0046,
0x0037, 0x2000, 0xEA60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
// Data to be loaded into the Main register memory space
const unsigned short MC33816_main_config[29] =
{
0x0003, 0x1FFE, 0x0000, 0x1200, 0x0000, 0x0000, 0x0001, 0x0000, 0x001F, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
// Data to be loaded into the CH1 register memory space
const unsigned short MC33816_ch1_config[19] =
{
0x0008, 0x0000, 0x0000, 0x0000, 0x0403, 0x0000, 0x0000, 0x003E, 0x45B4, 0x6FB5,
0x0000, 0x002C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
// Data to be loaded into the CH2 register memory space
const unsigned short MC33816_ch2_config[19] =
{
0x0008, 0x0000, 0x0000, 0x0000, 0x0800, 0x0000, 0x0000, 0x002B, 0x218C, 0xDCB6,
0x0000, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
// Data to be loaded into the IO register memory space
const unsigned short MC33816_io_config[44] =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0063, 0x0104, 0x0800, 0x0610, 0x0041, 0x0098,
0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0041, 0x0041, 0x0000, 0x0004, 0x1000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F7F, 0x7F7F,
0x007F, 0x0000, 0x0000, 0x0000
};
// Data to be loaded into the Diag register memory space
const unsigned short MC33816_diag_config[44] =
{
0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000,
0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x001E, 0x0000,
0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000,
0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001
};

View File

@ -8,6 +8,13 @@
#ifndef HW_LAYER_MC33816_DATA_H_
#define HW_LAYER_MC33816_DATA_H_
extern unsigned short MC33816_code_RAM1[105]; // CODE RAM CH 1
extern const unsigned short MC33816_code_RAM1[62]; // CODE RAM CH 1
extern const unsigned short MC33816_code_RAM2[43]; // CODE RAM CH 2
extern const unsigned short MC33816_data_RAM[128]; // DATA RAM
extern const unsigned short MC33816_main_config[29]; // main configurations
extern const unsigned short MC33816_ch1_config[19]; // CH 1 configurations
extern const unsigned short MC33816_ch2_config[19]; // CH 2 configurations
extern const unsigned short MC33816_io_config[44]; // IO configurations
extern const unsigned short MC33816_diag_config[44]; // diag configurations
#endif /* HW_LAYER_MC33816_DATA_H_ */