D语言中CRC寄存器的操作
auto crc32of(size_t len,scope const(uint*) src)
{
import mculib.arch.support;
enum BitsSize = CRC.IDR.IDR.Bits_Type.sizeof*8;
enum ubyte Busymask = 1u << (BitsSize - 1);
enum unBusymask = MakerMask4Slice!(0,BitsSize-1);
enum shared(ubyte)* mIDR = cast(shared(ubyte)*)(CRC.IDR.RegistersAddress);
if(!RCC.AHB1ENR.CRCEN.value){
scope(exit){
if(*mIDR == 0x00){
RCC.AHB1ENR.CRCEN.value = 0;
}
}
RCC.AHB1ENR.CRCEN.value = 1;
*mIDR = 0x00;
}
ubyte oldIdr = 0;
ubyte newIdr = 0;
do{
oldIdr = atomicLoad(*mIDR);
newIdr = oldIdr ;
newIdr++;
}while(!cas(mIDR,oldIdr,newIdr));
do{
oldIdr = atomicLoad(*mIDR) & unBusymask;
newIdr = oldIdr | Busymask;
}while(!cas(mIDR,oldIdr,newIdr));
scope(exit){
do{
oldIdr = atomicLoad(*mIDR) & unBusymask;
newIdr = oldIdr ;
newIdr --;
}while(!cas(mIDR,oldIdr,newIdr));
}
CRC.CR.CR.value = 1;
auto ptr = cast(uint*)src;
while(len--){
CRC.DR.value = *ptr++;
}
return CRC.DR.value;
}
- 重点:
小心中断,尽可能不在中断内调用任何函数,中断内调用函数会涉及到不少烦心事情的
操作寄存器时需要考虑寄存器的准备时间,尽量调用后核对一下状态或用提交刷新一下内存
文章内没有实现代码的函数可以在 https://gitee.com/sdvcn/mculib4d 内查阅到相关代码