00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <p18cxxx.h>
00013 #include <delays.h>
00014 #include <string.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #pragma config FOSC = IRC, PLLEN = OFF, PCLKEN = ON
00030 #pragma config FCMEN = OFF, BOREN = OFF, PWRTEN = OFF
00031 #pragma config WDTEN = OFF, MCLRE = ON, LVP = OFF
00032
00033
00034 #define FOSC 16000000L
00035 #define BAUD_RATE 19200
00036 #define MAX_CMD 20
00037
00038 rom char prompt[] = "\nSPI>";
00039 rom char errcmd[] = "\nUnknown Command!\n";
00040 char sdigit[3]={'0','0','\0'};
00041 unsigned char hexval[5];
00042 unsigned char spi_cs, spi_freq, spi_bus;
00043
00044
00045 #define MAX_HELP 60
00046
00047
00048
00049 rom char helpscr[][MAX_HELP]=
00050 {"PICJazz Board: PIC18F14K22 UART to SPI Gateway\n",
00051 "http://www.ermicro.com/blog\n",
00052 "\nSPI Gateway Commands:\n\n",
00053 "[A] - Auto SPI Data Transmission (Hex Format)\n",
00054 " Example: A0x40,0x12,0xFF\n",
00055 "[C] - Clear Screen\n",
00056 "[D] - Display SPI Configuration\n",
00057 "[F] - SPI Clocks F0-Fosc/4, F1-Fosc/16, and F2-Fosc/64\n",
00058 "[M] - SPI Bus Modes M0, M1, M2, and M3\n",
00059 " Mode 0 - CKP=0,CKE=1 : Mode 1 - CKP=0,CKE=0\n",
00060 " Mode 2 - CKP=1,CKE=1 : Mode 3 - CKP=1,CKE=0\n",
00061 "[R] - Received SPI Slave Data\n",
00062 "[S] - SPI Chip Select S0-Low and S1-High\n",
00063 "[T] - Transmit SPI Master Data:\n",
00064 " 0x - Hex Data Format: T0x8A\n",
00065 " 0b - Binary Data Format: T0b10001010\n",
00066 "[U] - Use default SPI Configuration\n",
00067 "[?] - Show Help\n"};
00068
00069
00070 void delay_ms(unsigned int ms)
00071 {
00072 do {
00073 Delay1KTCYx(4);
00074 } while(--ms);
00075 }
00076
00077 void uart_init(void)
00078 {
00079 TRISBbits.TRISB5 = 1;
00080 TRISBbits.TRISB7 = 0;
00081
00082
00083
00084
00085
00086 SPBRG = (int)(FOSC/(64UL * BAUD_RATE) - 1);
00087 TXSTA = 0b00100000;
00088 RCSTA = 0b10010000;
00089 BAUDCON=0x00;
00090 }
00091
00092 int _user_putc(char ch)
00093 {
00094 if (ch == '\n')
00095 _user_putc('\r');
00096
00097
00098 while(!PIR1bits.TXIF) continue;
00099 TXREG = ch;
00100 }
00101
00102 char _user_getc(void)
00103 {
00104
00105 while(!PIR1bits.RCIF) continue;
00106 return RCREG;
00107 }
00108
00109 void uart_gets(char *buf, unsigned char len)
00110 {
00111 unsigned char cnt;
00112
00113 cnt=0;
00114 while(cnt < len) {
00115 *buf = _user_getc();
00116 _user_putc(*buf);
00117 cnt++;
00118 if (*buf == '\r') {
00119 *buf='\0';
00120 break;
00121 }
00122 if (*buf == '\b') {
00123 _user_putc(32);
00124 _user_putc('\b');
00125 buf--;buf--;
00126 cnt--;
00127 }
00128 buf++;
00129 }
00130 *buf='\0';
00131
00132 _user_putc('\n');
00133 }
00134
00135 void uart_puts_P(rom char *buf)
00136 {
00137 while(*buf) {
00138 _user_putc(*buf);
00139 buf++;
00140 }
00141 }
00142
00143 void uart_puts(char *buf)
00144 {
00145 while(*buf) {
00146 _user_putc(*buf);
00147 buf++;
00148 }
00149 }
00150
00151 void ansi_cl(void)
00152 {
00153
00154 _user_putc(27);
00155 _user_putc('[');
00156 _user_putc('H');
00157 _user_putc(27);
00158 _user_putc('[');
00159 _user_putc('J');
00160 }
00161
00162 void ansi_me(void)
00163 {
00164
00165 _user_putc(27);
00166 _user_putc('[');
00167 _user_putc('0');
00168 _user_putc('m');
00169 }
00170
00171 void disp_help(void)
00172 {
00173 unsigned char i;
00174
00175
00176 for(i=0;i < (sizeof(helpscr)/MAX_HELP);i++) {
00177 uart_puts_P(helpscr[i]);
00178 }
00179 }
00180
00181 void spi_init(void)
00182 {
00183
00184 TRISCbits.TRISC6 = 0;
00185 TRISCbits.TRISC7= 0;
00186 TRISBbits.TRISB4= 1;
00187 TRISBbits.TRISB6= 0;
00188
00189 SSPSTAT = 0x40;
00190 SSPCON1 = 0x20;
00191 PORTCbits.RC6 = 1;
00192
00193
00194 spi_cs=1;
00195 spi_freq=0;
00196 spi_bus=0;
00197 }
00198
00199 void spi_mode(unsigned char cmd)
00200 {
00201 switch(cmd) {
00202 case '0':
00203 spi_bus=0;
00204 SSPSTATbits.CKE=1;
00205 SSPCON1bits.CKP=0;
00206 uart_puts_P((rom char *)"SPI Mode 0\n");
00207 break;
00208 case '1':
00209 spi_bus=1;
00210 SSPSTATbits.CKE=0;
00211 SSPCON1bits.CKP=0;
00212 uart_puts_P((rom char *)"SPI Mode 1\n");
00213 break;
00214 case '2':
00215 spi_bus=2;
00216 SSPSTATbits.CKE=1;
00217 SSPCON1bits.CKP=1;
00218 uart_puts_P((rom char *)"SPI Mode 2\n");
00219 break;
00220 case '3':
00221 spi_bus=3;
00222 SSPSTATbits.CKE=0;
00223 SSPCON1bits.CKP=1;
00224 uart_puts_P((rom char *)"SPI Mode 3\n");
00225 break;
00226 default:
00227 uart_puts_P(errcmd);
00228 }
00229 }
00230
00231 void spi_slavecs(unsigned char cmd)
00232 {
00233 switch(cmd) {
00234 case '0':
00235 spi_cs=0;
00236 PORTCbits.RC6 = 0;
00237 uart_puts_P((rom char *)"SPI Chip Select Low\n");
00238 break;
00239 case '1':
00240 spi_cs=1;
00241 PORTCbits.RC6 = 1;
00242 uart_puts_P((rom char *)"SPI Chip Select High\n");
00243 break;
00244 default:
00245 uart_puts_P(errcmd);
00246 }
00247 }
00248
00249 void spi_clock(unsigned char cmd)
00250 {
00251 switch(cmd) {
00252 case '0':
00253 spi_freq=0;
00254 SSPCON1 &= 0xF0;
00255 uart_puts_P((rom char *)"SPI Clock Fosc/4\n");
00256 break;
00257 case '1':
00258 spi_freq=1;
00259 SSPCON1 &= 0xF1;
00260 uart_puts_P((rom char *)"SPI Clock Fosc/16\n");
00261 break;
00262 case '2':
00263 spi_freq=2;
00264 SSPCON1 &= 0xF2;
00265 uart_puts_P((rom char *)"SPI Clock Fosc/64\n");
00266 break;
00267 default:
00268 uart_puts_P(errcmd);
00269 }
00270 }
00271
00272
00273 char *num2hex(unsigned char num)
00274 {
00275 unsigned char idx;
00276 char hexval[]={"0123456789ABCDEF"};
00277
00278 idx = 0;
00279 while(num >= 16){
00280 idx++;
00281 num -= 16;
00282 }
00283
00284 sdigit[0]='0';
00285 if (idx > 0)
00286 sdigit[0]=hexval[idx];
00287
00288 sdigit[1]=hexval[num];
00289 return sdigit;
00290 }
00291
00292 int hex2num(char *cmd)
00293 {
00294 unsigned char num;
00295
00296 if (strlen(cmd) != 2)
00297 return -1;
00298
00299
00300 num=0;
00301 while(*cmd) {
00302 num = num << 4;
00303 if (*cmd >= 'A' && *cmd <= 'F') {
00304 num += *cmd - 55;
00305 } else if (*cmd >= 'a' && *cmd <= 'f') {
00306 num += *cmd - 87;
00307 } else if (*cmd >= '0' && *cmd <= '9') {
00308 num += *cmd - 48;
00309 } else {
00310 return -1;
00311 }
00312 cmd++;
00313 }
00314 return num;
00315 }
00316
00317 int bin2num(char *cmd)
00318 {
00319 unsigned char num,cnt;
00320 unsigned char binval[]={128,64,32,16,8,4,2,1};
00321
00322 if (strlen(cmd) != 8 )
00323 return -1;
00324
00325
00326 num=0;
00327 for(cnt=0;cnt<8;cnt++) {
00328 if (cmd[cnt] >= '0' && cmd[cnt] <= '1') {
00329 num += binval[cnt] * (cmd[cnt] - 48);
00330 } else
00331 return -1;
00332 }
00333 return num;
00334 }
00335
00336 unsigned char SPI_WriteRead(unsigned char data)
00337 {
00338 unsigned char slave_data;
00339
00340
00341 uart_puts_P((rom char *)"SPI Master Send: 0x");
00342 uart_puts(num2hex(data));
00343 SSPBUF = data;
00344
00345
00346 while(!SSPSTATbits.BF);
00347
00348
00349 slave_data=SSPBUF;
00350 uart_puts_P((rom char *)", SPI Slave Return: 0x");
00351 uart_puts(num2hex(slave_data)); _user_putc('\n');
00352
00353 return(slave_data);
00354 }
00355
00356 void spi_transmit(char *cmd)
00357 {
00358 unsigned char data;
00359
00360 if (*cmd != '0') {
00361 uart_puts_P(errcmd);
00362 return;
00363 }
00364 cmd++;
00365
00366 switch(*cmd) {
00367 case 'x':
00368 case 'X':
00369 data=hex2num(cmd + 1);
00370 if (data >= 0)
00371 data=SPI_WriteRead((unsigned char) data);
00372 else
00373 uart_puts_P(errcmd);
00374 break;
00375 case 'b':
00376 case 'B':
00377 data=bin2num(cmd + 1);
00378 if (data >= 0)
00379 data=SPI_WriteRead((unsigned char) data);
00380 else
00381 uart_puts_P(errcmd);
00382 break;
00383 default:
00384 uart_puts_P(errcmd);
00385 }
00386 }
00387
00388 void auto_transmit(char *cmd)
00389 {
00390 unsigned char cnt,hexcnt;
00391
00392
00393 spi_slavecs('0');
00394
00395
00396 cnt=0;
00397 hexcnt=0;
00398 while(cmd[cnt]) {
00399 if (cmd[cnt] != ',') {
00400 hexval[hexcnt++]=cmd[cnt];
00401 if (hexcnt > 4) {
00402 uart_puts_P(errcmd);
00403 return;
00404 }
00405 } else {
00406 hexval[hexcnt]='\0';
00407 spi_transmit(hexval);
00408 hexcnt=0;
00409 }
00410 cnt++;
00411 }
00412
00413
00414 hexval[hexcnt]='\0';
00415 spi_transmit(hexval);
00416
00417
00418 spi_slavecs('1');
00419 }
00420
00421 void disp_config()
00422 {
00423
00424 uart_puts_P((rom char *)"SPI CS Status: ");
00425 switch (spi_cs) {
00426 case 0:
00427 uart_puts_P((rom char *)"Low");
00428 break;
00429 case 1:
00430 uart_puts_P((rom char *)"High");
00431 break;
00432 default:
00433 uart_puts_P(errcmd);
00434 }
00435
00436
00437 uart_puts_P((rom char *)", SPI Clock: ");
00438 switch (spi_freq) {
00439 case 0:
00440 uart_puts_P((rom char *)"Fosc/4");
00441 break;
00442 case 1:
00443 uart_puts_P((rom char *)"Fosc/16");
00444 break;
00445 case 2:
00446 uart_puts_P((rom char *)"Fosc/64");
00447 break;
00448 default:
00449 uart_puts_P(errcmd);
00450 }
00451
00452
00453 uart_puts_P((rom char *)", SPI Bus Mode: ");
00454 switch (spi_bus) {
00455 case 0:
00456 _user_putc('0');
00457 break;
00458 case 1:
00459 _user_putc('1');
00460 break;
00461 case 2:
00462 _user_putc('2');
00463 break;
00464 case 3:
00465 _user_putc('3');
00466 break;
00467 default:
00468 uart_puts_P(errcmd);
00469 }
00470 _user_putc('\n');
00471 }
00472
00473 void disp_header()
00474 {
00475 uart_puts_P(helpscr[0]);
00476 uart_puts_P(helpscr[1]);
00477 uart_puts_P((rom char *)"\nEnter SPI Command (? for help):\n");
00478 }
00479
00480 void main(void)
00481 {
00482 char cmd[MAX_CMD + 1];
00483 unsigned char data;
00484
00485 OSCCON=0x70;
00486
00487 TRISC = 0x00;
00488 TRISA = 0x30;
00489 TRISB = 0x00;
00490 ANSEL = 0x00;
00491 ANSELH = 0x00;
00492
00493
00494 uart_init();
00495 delay_ms(1);
00496
00497
00498 spi_init();
00499
00500
00501 ansi_cl();
00502 ansi_me();
00503 ansi_cl();
00504 disp_header();
00505
00506 for(;;) {
00507 uart_puts_P(prompt); uart_gets(cmd,MAX_CMD);
00508 switch (cmd[0]) {
00509 case 'a':
00510 case 'A':
00511 auto_transmit(cmd + 1);
00512 break;
00513 case 'c':
00514 case 'C':
00515 if (cmd[1] != '\0') {
00516 uart_puts_P(errcmd);
00517 } else {
00518 ansi_cl();
00519 disp_header();
00520 }
00521 break;
00522 case 'd':
00523 case 'D':
00524 if (cmd[1] != '\0') {
00525 uart_puts_P(errcmd);
00526 } else {
00527 disp_config();
00528 }
00529 break;
00530 case 'f':
00531 case 'F':
00532 spi_clock(cmd[1]);
00533 break;
00534 case 'm':
00535 case 'M':
00536 spi_mode(cmd[1]);
00537 break;
00538 case 'r':
00539 case 'R':
00540 if (cmd[1] != '\0') {
00541 uart_puts_P(errcmd);
00542 } else {
00543 data=SPI_WriteRead(0x00);
00544 uart_puts_P((rom char *)"SPI Read: 0x");
00545 uart_puts(num2hex(data)); _user_putc('\n');
00546 }
00547 break;
00548 case 's':
00549 case 'S':
00550 spi_slavecs(cmd[1]);
00551 break;
00552 case 't':
00553 case 'T':
00554 spi_transmit(cmd + 1);
00555 break;
00556 case 'u':
00557 case 'U':
00558 if (cmd[1] != '\0') {
00559 uart_puts_P(errcmd);
00560 } else {
00561 spi_init();
00562 uart_puts_P((rom char *)"Default SPI Config:\n");
00563 disp_config();
00564 }
00565 break;
00566 case '?':
00567 if (cmd[1] != '\0')
00568 uart_puts_P(errcmd);
00569 else
00570 disp_help();
00571 break;
00572 default:
00573 uart_puts_P(errcmd);
00574 }
00575 }
00576 }
00577
00578