📄 main.c
字号:
//***************************************************************************
// showstatus - show current SPI port settings
//***************************************************************************
void showstatus(char displaymode)
{
char tmp, ix=0;
if(displaymode == STATLIST) USART_Transmit(' '); // some padding
for(;;) // loop until the return statement is executed
{
send_str(status[ix]);
switch(ix++){
case 1: // actual frequency
tmp = (SPCR & 0x03) | ((SPSR & 1) << 2);
USART_Transmit(htoa(tmp));
if(displaymode == STATLIST) send_str(freq[tmp]);
break;
case 2: // actual SS status
USART_Transmit(htoa((PORT_SPI & (1<<P_SS)) >> P_SS));
break;
case 3: // actual auto mode
USART_Transmit(htoa(ss_auto));
if(displaymode == STATLIST)
{
if(!ss_auto) send_str(auto0);
else if(ss_auto == 1) send_str(auto1);
else send_str(auto2);
}
break;
case 4: // actual data order
tmp = (SPCR & (1 << DORD)) >> DORD;
USART_Transmit(htoa(tmp));
if((displaymode == STATLIST) && !tmp) send_str(bit0);
if((displaymode == STATLIST) && tmp) send_str(bit1);
break;
case 5: // actual mode
USART_Transmit(htoa((SPCR & 0x0C) >> 2));
return; // nothing more to display
}// end switch
if(displaymode == STATLIST) send_str(nullprompt); // next line
else send_str(gap); // or some padding
}// end for
}
//***************************************************************************
// hexsequence - fetch, check and transmit a multi-byte sequence
//***************************************************************************
void hexsequence(void)
{
char tx_str[MAXSEQ*2]; // enough storage for ascii encoded bytes
char rx_str[MAXSEQ]; // storage for returned characters
char length;
int ix;
for (ix = 0;ix < MAXSEQ*2;ix++) // get character string
{
if (!(ix % 2)) USART_Transmit(':'); // separator every 2nd character
tx_str[ix] = getnextchar();
if (tx_str[ix] == '\r') break; // detect 'enter' key pressed
if (!isxdigit(tx_str[ix])) // detect invalid characters entered
{
send_str(error1); // abort entry for illegal character
return; // exit immediately
}
if (tx_str[ix] > '9') tx_str[ix] -= 7;
// A-F shifted to be consecutive from 0-9
tx_str[ix] -= 0x30; // Remove ASCII offset
}
length = ix/2; // store number of full bytes entered
// ensure SS pin is in idle condition if auto toggle is on
if(!ss_auto) sspinadjust(1); // make SS pin high
if(ss_auto == 1) sspinadjust(0); // make SS pin low
// At this point, tx_str contains length*2 valid half-bytes.
// The conversion to bytes, SPI exchange and received byte display are
// now carried out in seperate loops to ensure the SPI transmission takes
// place in the shortest time period.
for (ix = 0;ix < length;ix++) // convert half-bytes to bytes
tx_str[ix] = (tx_str[ix*2] << 4) | tx_str[(ix*2)+1]; // nibbles combined
if(ss_auto != 2) sspinadjust(ss_auto); // Auto toggle SS pin if mode is on
for (ix = 0;ix < length;ix++) // transmit the sequence
rx_str[ix] = SPI_MasterTransmit(tx_str[ix]); // SPI byte exchange
// restore SS pin to idle condition if auto toggle is on
if(!ss_auto) sspinadjust(1); // make SS pin high
if(ss_auto == 1) sspinadjust(0); // make SS pin low
for (ix = 0;ix < length;ix++) // Display the exchange
{
send_str(nullprompt);
USART_Transmit( htoa((tx_str[ix] & 0xf0) >> 4) );//display upper nibble
USART_Transmit( htoa(tx_str[ix] & 0x0F) ); //display lower nibble
send_str(exchange);
USART_Transmit( htoa((rx_str[ix] & 0xf0) >> 4) );//display upper nibble
USART_Transmit( htoa(rx_str[ix] & 0x0F) ); //display lower nibble
}
}
//***************************************************************************
// setfreq - set the SPI SCK frequency
//***************************************************************************
void setfreq(void)
{
char tmp;
tmp = getnextchar();
tmp -= 0x30; // Remove ASCII offset
if (tmp < 8) // a valid frequency value (unsigned, so no negative values)
{
SPCR &= 0xFC; // mask off current SPR bits (bit 1 & 0)
SPCR |= tmp & 0x03; // set new value using two lsb of selection number
if(tmp & 0x04) SPSR |= (1 << SPI2X); // for selection 4-7 set SPI2X
else SPSR &= ~(1 << SPI2X); // otherwise clear SPI2X
send_str(newstat);
showstatus(STATLIST);
}
else send_str(error1); // abort entry for illegal second character
}
//***************************************************************************
// setsspin - modify the state of SS pin on SPI port
//***************************************************************************
void setsspin(void)
{
char tmp;
tmp = getnextchar();
tmp -= 0x30; // Remove ASCII offset
if (tmp < 2) // a valid bit value (unsigned, so no negative values)
{
sspinadjust(tmp); // change pin level
send_str(newstat);
showstatus(STATLIST);
}
else send_str(error1); // abort entry for illegal second character
}
//***************************************************************************
// sspinadjust - modify the physical SS pin on SPI port
//***************************************************************************
void sspinadjust(char level)
{
if(level) PORT_SPI |= (1 << P_SS); // make SS pin high
else PORT_SPI &= ~(1 << P_SS); // make SS pin low
ss_level = level;
}
//***************************************************************************
// setautomode - store the required mode for SS pin auto toggle
//***************************************************************************
void setautomode(void)
{
char tmp;
tmp = getnextchar();
tmp -= 0x30; // Remove ASCII offset
if (tmp < 3) // a valid bit value (unsigned, so no negative values)
{
ss_auto = tmp; // auto mode stored
send_str(newstat);
showstatus(STATLIST);
}
else send_str(error1); // abort entry for illegal second character
}
//***************************************************************************
// setorder - set the bit transmission order
//***************************************************************************
void setorder(void)
{
char tmp;
tmp = getnextchar();
tmp -= 0x30; // Remove ASCII offset
if (tmp < 2) // a valid bit value (unsigned, so no negative values)
{
if(tmp) SPCR |= (1 << DORD); // set DORD bit
else SPCR &= ~(1 << DORD); // clear DORD bit
send_str(newstat);
showstatus(STATLIST);
}
else send_str(error1); // abort entry for illegal second character
}
//***************************************************************************
// setmode - set the SPI communications mode
//***************************************************************************
void setmode(void)
{
char tmp;
tmp = getnextchar();
tmp -= 0x30; // Remove ASCII offset
if (tmp < 4) // a valid mode value (unsigned, so no negative values)
{
SPCR &= 0xF3; // mask off current CPOL/CPHA bits (bit 3 & 2)
SPCR |= tmp << 2; // set new value
send_str(newstat);
showstatus(STATLIST);
}
else send_str(error1); // abort entry for illegal second character
}
//***************************************************************************
// writeconfig - save the current configuration in EEPROM
//***************************************************************************
void writeconfig(void)
{
__disable_interrupt(); // disable interrupts during EEPROM write
config1 = SPCR; // store SPCR register
config2 = SPSR; // store SPSR register
config3 = flags; // store global flag variable
checksum = 0 - (config1 + config2 + config3);// generate and store checksum
__enable_interrupt(); // Enable interrupts => enable UART interrupts
send_str(cfgwrite);
}
//***************************************************************************
// loadconfig - fetch the configuration from EEPROM
//***************************************************************************
void loadconfig(void)
{ // check for valid config - blank EEPROM will not give zero result
if (!((config1 + config2 + config3 + checksum) & 0xFF))
{
SPCR = config1; // restore SPCR register
SPSR = config2; // restore SPSR register
flags = config3; // restore global flag variable
sspinadjust(ss_level); // restore default SS pin level
send_str(config);
showstatus(STATLIST);
}
else send_str(noconfig);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -