📄 halp30p.nc
字号:
/*
* Author: Josh Herbach
* Revision: 1.0
* Date: 09/02/2005
*/
module HalP30P {
provides interface Init;
provides interface Flash; //does not allow writing into FLASH_PROTECTED_REGION
uses interface HplP30;
}
implementation {
#include <P30.h>
enum {
FLASH_STATE_READ_INACTIVE,
FLASH_STATE_PROGRAM,
FLASH_STATE_ERASE,
FLASH_STATE_READ_ACTIVE
};
uint8_t FlashPartitionState[FLASH_PARTITION_COUNT];
uint8_t init = 0, programBufferSupported = 2, currBlock = 0;
command error_t Init.init() {
int i = 0;
if(init != 0)
return SUCCESS;
init = 1;
for(i = 0; i < FLASH_PARTITION_COUNT; i++)
FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
return SUCCESS;
}
uint16_t writeHelper(uint32_t addr, uint8_t* data, uint32_t numBytes,
uint8_t prebyte, uint8_t postbyte){
uint32_t i = 0, j = 0, k = 0;
error_t status;
uint16_t buffer[FLASH_PROGRAM_BUFFER_SIZE];
if(numBytes == 0)
return FAIL;
if(addr % 2 == 1){
status = call HplP30.progWord(addr - 1, prebyte | (data[i] << 8));
i++;
if(status != SUCCESS)
return FAIL;
}
if(addr % 2 == numBytes % 2){
if(programBufferSupported == 1)
for(; i < numBytes; i = k){
for(j = 0, k = i; k < numBytes &&
j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
buffer[j] = data[k] | (data[k + 1] << 8);
status = call HplP30.progBuffer(addr + i, buffer, j);
if(status != SUCCESS)
return FAIL;
}
else
for(; i < numBytes; i+=2){
status = call HplP30.progWord(addr + i, (data[i + 1] << 8) | data[i]);
if(status != SUCCESS)
return FAIL;
}
}
else{
if(programBufferSupported == 1)
for(; i < numBytes - 1; i = k){
for(j = 0, k = i; k < numBytes - 1 &&
j < FLASH_PROGRAM_BUFFER_SIZE; j++, k+=2)
buffer[j] = data[k] | (data[k + 1] << 8);
status = call HplP30.progBuffer(addr + i, buffer, j);
if(status != SUCCESS)
return FAIL;
}
else
for(; i < numBytes - 1; i+=2){
status = call HplP30.progWord(addr + i, (data[i + 1] << 8) | data[i]);
if(status != SUCCESS)
return FAIL;
}
status = call HplP30.progWord(addr + i, data[i] | (postbyte << 8));
if(status != SUCCESS)
return FAIL;
}
return SUCCESS;
}
void writeExitHelper(uint32_t addr, uint32_t numBytes){
uint32_t i = 0;
for(i = addr / FLASH_PARTITION_SIZE;
i < (numBytes + addr) / FLASH_PARTITION_SIZE;
i++)
FlashPartitionState[i] = FLASH_STATE_READ_INACTIVE;
}
command error_t Flash.write(uint32_t addr, uint8_t* data, uint32_t numBytes) {
uint32_t i;
uint16_t status;
uint8_t blocklen;
uint32_t blockAddr = (addr / P30_BLOCK_SIZE) * P30_BLOCK_SIZE;
if(addr + numBytes > 0x02000000) //not in the flash memory space
return FAIL;
if(addr < FLASH_PROTECTED_REGION)
return FAIL;
for(i = 0; i < FLASH_PARTITION_COUNT; i++)
if(i != addr / FLASH_PARTITION_SIZE &&
FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
return FAIL;
for(i = addr / FLASH_PARTITION_SIZE;
i < (numBytes + addr) / FLASH_PARTITION_SIZE;
i++)
if(FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE)
return FAIL;
for(i = addr / FLASH_PARTITION_SIZE;
i < (numBytes + addr) / FLASH_PARTITION_SIZE;
i++)
FlashPartitionState[i] = FLASH_STATE_PROGRAM;
atomic{
for(blocklen = 0, i = blockAddr;
i < addr + numBytes;
i += P30_BLOCK_SIZE, blocklen++)
call HplP30.blkUnlock(i); //unlock(i);
if(programBufferSupported == 2){
uint16_t testBuf[1];
if(addr % 2 == 0){
testBuf[0] = data[0] | ((*((uint8_t *)(addr + 1))) << 8);
status = call HplP30.progBuffer(addr, testBuf, 1);
}
else{
testBuf[0] = *((uint8_t *)(addr - 1)) | (data[0] << 8);
status = call HplP30.progBuffer(addr - 1, testBuf, 1);
}
if(status != SUCCESS)
programBufferSupported = 0;
else
programBufferSupported = 1;
}
}
if(blocklen == 1){
atomic status = writeHelper(addr,data,numBytes,0xFF,0xFF);
if(status == FAIL){
writeExitHelper(addr, numBytes);
return FAIL;
}
}
else{
uint32_t bytesLeft = numBytes;
atomic status = writeHelper(addr,data, blockAddr + P30_BLOCK_SIZE - addr,0xFF,0xFF);
if(status == FAIL){
writeExitHelper(addr, numBytes);
return FAIL;
}
bytesLeft = numBytes - (P30_BLOCK_SIZE - (addr - blockAddr));
for(i = 1; i < blocklen - 1; i++){
atomic status = writeHelper(blockAddr + i * P30_BLOCK_SIZE, (uint8_t *)(data + numBytes - bytesLeft),
P30_BLOCK_SIZE,0xFF,0xFF);
bytesLeft -= P30_BLOCK_SIZE;
if(status == FAIL){
writeExitHelper(addr, numBytes);
return FAIL;
}
}
atomic status = writeHelper(blockAddr + i * P30_BLOCK_SIZE, data + (numBytes - bytesLeft), bytesLeft, 0xFF,0xFF);
if(status == FAIL){
writeExitHelper(addr, numBytes);
return FAIL;
}
}
writeExitHelper(addr, numBytes);
return SUCCESS;
}
command error_t Flash.erase(uint32_t addr){
uint16_t status, i;
uint32_t j;
if(addr > 0x02000000) //not in the flash memory space
return FAIL;
if(addr < FLASH_PROTECTED_REGION)
return FAIL;
addr = (addr / P30_BLOCK_SIZE) * P30_BLOCK_SIZE;
for(i = 0; i < FLASH_PARTITION_COUNT; i++)
if(i != addr / FLASH_PARTITION_SIZE &&
FlashPartitionState[i] != FLASH_STATE_READ_INACTIVE &&
FlashPartitionState[i] != FLASH_STATE_READ_ACTIVE)
return FAIL;
if(FlashPartitionState[addr / FLASH_PARTITION_SIZE] != FLASH_STATE_READ_INACTIVE)
return FAIL;
FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_ERASE;
for(j = 0; j < P30_BLOCK_SIZE; j++){
uint32_t tempCheck = *(uint32_t *)(addr + j);
if(tempCheck != 0xFFFFFFFF)
break;
if(j == P30_BLOCK_SIZE - 1){
FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_READ_INACTIVE;
return SUCCESS;
}
}
atomic{
call HplP30.blkUnlock(addr);
// status = eraseFlash(addr);
status = call HplP30.blkErase(addr);
}
FlashPartitionState[addr / FLASH_PARTITION_SIZE] = FLASH_STATE_READ_INACTIVE;
if(status != SUCCESS)
return FAIL;
return SUCCESS;
}
// WARNING: Check the endien of this
command error_t Flash.read(uint32_t addr, uint8_t* buf, uint32_t len) {
error_t status;
uint8_t databyte;
/*
uint16_t dataword;
while(len > 1) {
atomic {
status = call HplP30.readWordBurst(addr, &dataword);
}
if(status != SUCCESS)
return FAIL;
*((uint16_t*) buf) = dataword;
addr += 2;
buf += 2;
len -= 2;
}
if(len == 1) {
atomic {
status = call HplP30.readWordBurst(addr, &dataword);
}
if(status != SUCCESS)
return FAIL;
*buf = (uint8_t) dataword;
}
*/
while(len > 0) {
atomic {
status = call HplP30.readByteBurst(addr, &databyte);
}
if(status != SUCCESS)
return FAIL;
*buf = databyte;
addr += 1;
buf += 1;
len -= 1;
}
return SUCCESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -