MC33PT2000控制主要功能函数代码详解三
11、void download_register(int r_target)
11.1、源代码
用途:通过spi写入寄存器(如main、io、channel、diag寄存器)
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function name : download_register
// Description : Downloads register configurations via SPI.
// Return type : void
// Argument : int r_target
/////////////////////////////////////////////////////////////////////////////////////////////////
void download_register(int r_target)
{int n = 0; // used for loop for writing data to the chipunsigned short r_start_address = 0; // start addressunsigned short r_size = 0; // size of configuration dataunsigned short r_command = 0; // command dataunsigned short r_data = 0; // configuration dataunsigned short remainder_size = 0; // remainder sizeunsigned short *reg_ptr = NULL; // pointer to array of data to be sent to the chipswitch (r_target) // selects target{case CH1_REG: // channel 1 configurationsr_start_address = ch1_flash_enable;reg_ptr = PT2000_ch1_config;r_size = sizeof(PT2000_ch1_config) / 2; // number of words to be sentbreak;case CH2_REG: // channel 2 configurationsr_start_address = ch2_flash_enable;reg_ptr = PT2000_ch2_config;r_size = sizeof(PT2000_ch2_config) / 2; // number of words to be sentbreak;case CH3_REG: // channel 3 configurationsr_start_address = ch3_flash_enable;reg_ptr = PT2000_ch3_config;r_size = sizeof(PT2000_ch3_config) / 2; // number of words to be sentbreak;case DIAG_REG: // diagnostic configurationsr_start_address = diag_ls1_diag_config1;reg_ptr = PT2000_diag_config;r_size = sizeof(PT2000_diag_config) / 2; // number of words to be sentbreak;case IO_REG: // IO configurationsr_start_address = io_fbk_sens_uc0_ch1_part1;reg_ptr = PT2000_io_config;r_size = sizeof(PT2000_io_config) / 2; // number of words to be sentbreak;case MAIN_REG: // main configurationsr_start_address = main_Clock_Prescaler;reg_ptr = PT2000_main_config;r_size = sizeof(PT2000_main_config) / 2; // number of words to be sentbreak;default:break;}// Select common page memory areasend_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100);// Set the maximum watchdog timeoutsend_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F);do{// If the size of the transfer is greater than the maximum SPI burst// transfer size, set the size to the maximum SPI burst size and store// the remainder size for use in the next SPI transferif (r_size > MAX_SPI_MODE_A_TRANSFER_SIZE){remainder_size = r_size - MAX_SPI_MODE_A_TRANSFER_SIZE;r_size = MAX_SPI_MODE_A_TRANSFER_SIZE;}else{// The size is <= MAX_SPI_MODE_A_TRANSFER_SIZE// so there is no remaining data to be sentremainder_size = 0;}// Build the control word to be sentr_command = r_start_address << 5;r_command += r_size;// Write a control word indicating the address and the number of words to be sentsend_16bit_SPI(r_command);for (n = 0; n < r_size; n++){// If this is the first register for ch1, ch2, or ch3 send 0 so the flash and dual// microcores are not enabledif( (n == 0) && ((r_target == CH1_REG) || (r_target == CH2_REG) || (r_target == CH3_REG)) ){r_data = 0;}else{r_data = *reg_ptr; // set data to be sent}send_16bit_SPI(r_data); // send datareg_ptr++; // update data pointer}r_start_address += r_size; // update the start addressr_size = remainder_size; // set size to the remaining amount of data} while (remainder_size > 0);// For channels 1, 2, & 3 program the flash enable register using the the// first entry in the channel's configuration tableswitch (r_target){case CH1_REG:// Program the ch1 flash enable registersend_single_PT2000_SPI_Cmd(WRITE, ch1_flash_enable, PT2000_ch1_config[0]);break;case CH2_REG:// Program the ch2 flash enable registersend_single_PT2000_SPI_Cmd(WRITE, ch2_flash_enable, PT2000_ch2_config[0]);break;case CH3_REG:// Program the ch3 flash enable registersend_single_PT2000_SPI_Cmd(WRITE, ch3_flash_enable, PT2000_ch3_config[0]);break;default:break;}} // end download_register
11.2、代码解析
1)int n = 0;
定义for循环的n变量,初始化值为0
2)unsigned short r_start_address = 0;
定义寄存器的起始地址,初始化值为0
3)unsigned short r_size = 0;
定义寄存器的长度(即数量),初始化值为0
4)unsigned short r_command = 0;
定义数据命令还是指令命令,初始化值为0(表示数据命令)
5)unsigned short r_data = 0;
定义缓存要发的数据变量
6)unsigned short remainder_size = 0;
定义还剩未发的数据的数量
7)unsigned short *reg_ptr = NULL;
定义数据块指针,指向要发的数据块
8)switch (r_target)
选择开关,可选择CH1_REG、CH2_REG、CH3_REG、DIAG_REG、IO_REG及MAIN_REG
9)case CH1_REG: r_start_address = ch1_flash_enable;reg_ptr = PT2000_ch1_config;
r_size = sizeof(PT2000_ch1_config) / 2;break;
设置channel1寄存器的起始地址、要写的寄存器配置表、寄存器的长度。
各参数如下:
#define ch1_flash_enable 0x100
数据表可到PT2000_LoadData.c文件里寻找
10)case CH2_REG: r_start_address = ch2_flash_enable;reg_ptr = PT2000_ch2_config;
r_size = sizeof(PT2000_ch2_config) / 2;break;
类似于9)
11)case CH3_REG: r_start_address = ch3_flash_enable;reg_ptr = PT2000_ch3_config;
r_size = sizeof(PT2000_ch3_config) / 2;break;
类似于9)
12)case DIAG_REG: r_start_address = diag_ls1_diag_config1;reg_ptr = PT2000_diag_config;r_size = sizeof(PT2000_diag_config) / 2;break;
设置diag寄存器的起始地址、要写的寄存器配置表、寄存器的长度。
各参数如下:
#define diag_ls1_diag_config1 0x1C0
数据表可到PT2000_LoadData.c文件里寻找
13)case IO_REG: r_start_address = io_fbk_sens_uc0_ch1_part1;reg_ptr = PT2000_io_config;r_size = sizeof(PT2000_io_config) / 2;break;
设置io寄存器的起始地址、要写的寄存器配置表、寄存器的长度。
各参数如下:
#define io_fbk_sens_uc0_ch1_part1 0x154
数据表可到PT2000_LoadData.c文件里寻找
14)case MAIN_REG: r_start_address = main_Clock_Prescaler;reg_ptr = PT2000_main_config;r_size = sizeof(PT2000_main_config) / 2;break;
设置main寄存器的起始地址、要写的寄存器配置表、寄存器的长度。
各参数如下:
#define main_Clock_Prescaler 0x1A0
数据表可到PT2000_LoadData.c文件里寻找
15)default: break;
如不在开关选择范围直接退出开关选择。
16)send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100);
向0x3FF寄存器写入0x100(即向下图的bit8写入1),即为选择公共页(即寄存器页,包含main、io、channel、diag等寄存器)
#define selection_register 0x3FF
16)send_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F);
向0x1A9寄存器写入0x1F,即设置watchdog参数
#define main_SPI_config 0x1A9
watchdog计算过程如下
tWATCHDOG = tCKSYS * ((watchdog + 1) x 32768) = 1/24MHz x((0x1F+1)x32768) = 43.69ms
17)do{.....}
执行写入除CH1_REG/CH2_REG/CH3_REG寄存器外,即写入MAIN/IO/DIAG寄存器
18)switch (r_target) { ....}
通过SPI写入CH1_REG/CH2_REG/CH3_REG寄存器
12、void download_RAM(int target)
12.1、源代码
用途:通过spi写入数据到代码RAM和数据RAM里
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function name : download_RAM
// Description : Downloads code RAM or data RAM via SPI.
// Return type : void
// Argument : int target
/////////////////////////////////////////////////////////////////////////////////////////////////
void download_RAM(int target)
{unsigned short memory_area = 0; // memory areaunsigned short start_address = 0; // start addressunsigned short codeWidthRegAddr = 0; // code width register addressunsigned short size = 0; // size of RAM dataunsigned short command = 0; // command dataunsigned short data = 0; // RAM dataunsigned int k = 0; // used in loop for writing RAM data to the chipunsigned short * RAM_ptr = NULL; // pointer to array of data to be sent to the chip// Select common page memory areasend_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100);// Set the maximum watchdog timeoutsend_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F);// Select targetswitch (target){case CODE_RAM1:memory_area = 0x1;start_address = 0;codeWidthRegAddr = ch1_code_width;RAM_ptr = PT2000_code_RAM1;size = sizeof(PT2000_code_RAM1) / 2; // gets number of words to be sentbreak;case CODE_RAM2:memory_area = 0x2;start_address = 0;codeWidthRegAddr = ch2_code_width;RAM_ptr = PT2000_code_RAM2;size = sizeof(PT2000_code_RAM2) / 2; // gets number of words to be sentbreak;case CODE_RAM3:memory_area = 0x4;start_address = 0;codeWidthRegAddr = ch3_code_width;RAM_ptr = PT2000_code_RAM3;size = sizeof(PT2000_code_RAM3) / 2; // gets number of words to be sentbreak;case DATA_RAM:memory_area = 0x0100;start_address = 0;RAM_ptr = PT2000_data_RAM;size = sizeof(PT2000_data_RAM) / 2; // gets number of words to be sentbreak;default:break;}// Set the code width register only if code RAM is being downloadedif (target != DATA_RAM){// Set the code width register with the size of the downloadsend_single_PT2000_SPI_Cmd(WRITE, codeWidthRegAddr, size);}// Send command for memory area selectionsend_single_PT2000_SPI_Cmd(WRITE, selection_register, memory_area);command = start_address << 5;send_16bit_SPI(command); // sends start address commandfor (k = 0; k < size; k++) // downloads RAM{data = *RAM_ptr; // retrieves data to be sentsend_16bit_SPI(data); // sends dataRAM_ptr++;}
} //end download_RAM
12.2、代码解析
1)unsigned short memory_area = 0;
定义内存的长度变量
2)unsigned short start_address = 0;
定义内存的起始地址变量
3)unsigned short codeWidthRegAddr = 0;
定义代码的长度变量
4)unsigned short size = 0;
定义RAM的长度变量
5)unsigned short command = 0;
定义数据指令还是命令指令
6)unsigned short data = 0;
定义数据的缓存变量
7)定义for循环的变量
unsigned int k = 0;
8)unsigned short * RAM_ptr = NULL;
定义要发送数据的指针,指向要发送的数据块
9)send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100);
向0x3FF寄存器写入0x100(即向下图的bit8写入1),即为选择公共页(即寄存器页,包含main、io、channel、diag等寄存器)
#define selection_register 0x3FF
10)send_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F);
向0x1A9寄存器写入0x1F,即设置watchdog参数
#define main_SPI_config 0x1A9
11)switch (target)
开关选择code RAM1/2/3或data RAM
12)case CODE_RAM1: memory_area = 0x1;start_address = 0;codeWidthRegAddr = ch1_code_width;RAM_ptr = PT2000_code_RAM1;size = sizeof(PT2000_code_RAM1) / 2;break;
设置code ram1的内存区域、起始地址、代码长度、代码数据块的指针、数据长度等
参数可在以下获取
#define ch1_code_width 0x107
13)case CODE_RAM2: memory_area = 0x2;start_address = 0;codeWidthRegAddr = ch2_code_width;RAM_ptr = PT2000_code_RAM2;size = sizeof(PT2000_code_RAM2) / 2;break;
类似于12)
14)case CODE_RAM3: memory_area = 0x3;start_address = 0;codeWidthRegAddr = ch3_code_width;RAM_ptr = PT2000_code_RAM3;size = sizeof(PT2000_code_RAM3) / 2;break;
类似于12)
15)case DATA_RAM:start_address = 0;memory_area = 0x0100;RAM_ptr = PT2000_data_RAM;size = sizeof(PT2000_data_RAM) / 2;break;
16)default:break;
如果不在开关选择范围内,直接退出
17)if (target != DATA_RAM) {send_single_PT2000_SPI_Cmd(WRITE, codeWidthRegAddr, size);}
如果发送的数据code RAM数据,那么将代码长度size写入0x107(如是channel1)寄存器
#define ch1_code_width 0x107
18)send_single_PT2000_SPI_Cmd(WRITE, selection_register, memory_area);
选择内存区域。
如memory_area = 0x1表示选中CRAM 1
如memory_area = 0x2表示选中CRAM 2
如memory_area = 0x4表示选中CRAM 3
如memory_area = 0x100表示选中DRAM
#define selection_register 0x3FF
19)command = start_address << 5;for (k = 0; k < size; k++) {data = *RAM_ptr;
send_16bit_SPI(data); RAM_ptr++;}
写入数据到CRAM或DRAM