/* write_7366(): Writes bytes in array "bytearray" to register "reg". The number of bytes written depends on the reister and mode. Config registers will write 1 byte. Other registers will write the number of bytes specified by COUNTER_BYTES */ void write_7366(int module, int reg,unsigned char *bytearray) { unsigned char ir = (0x2 << 6 ) | (reg << 3); //Instruction unsigned char ReadData; if ( (reg == MDR0) || (reg == MDR1) || (reg == STR) ) { //One byte to write ss_low(module); delay(); //Setup time SpiChnPutC(SPICHN, ir); //Write instruction after TX buffer empty while(SpiChnRxBuffFull(SPICHN)==0); //Wait for RX buffer full ReadData = SpiChnGetC(SPICHN); //Read what was clocked in during last write (nothing) SpiChnPutC(SPICHN, bytearray[0]); //Clock out write byte after TX buffer empty while(SpiChnRxBuffFull(SPICHN)==0); //Wait for RX buffer full ReadData = SpiChnGetC(SPICHN); //Read what was clocked in during last write (garbage /dont care) ss_high(module); //End comm return; } if ( (reg == DTR) || (reg == CNTR) || (reg == OTR) ) { //1-4 bytes to read ss_low(module); delay(); //Setup time SpiChnPutC(SPICHN, ir); //Write instruction after TX buffer empty while(SpiChnRxBuffFull(SPICHN)==0); //Wait for RX buffer full ReadData = SpiChnGetC(SPICHN); //Read what was clocked in during last write (nothing) //Do reads int i; for (i=0;i<COUNTER_BYTES;i++) { SpiChnPutC(SPICHN, bytearray[i]); //Clock out byte after TX buffer empty while(SpiChnRxBuffFull(SPICHN)==0); //Wait for RX buffer full ReadData = SpiChnGetC(SPICHN); //Read what was clocked in during last write (don't care) } ss_high(module); //End comm return; } }
/******************************************************************** * Function: void ProcessIO(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function is a place holder for other user * routines. It is a mixture of both USB and * non-USB tasks. * * Note: None *******************************************************************/ void ProcessIO(void) { BYTE numBytesRead; //Blink the LEDs according to the USB device status // // User Application USB tasks // // If suspended, do nothing. if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; // If character received, echo it if(mUSBUSARTIsTxTrfReady()) { numBytesRead = getsUSBUSART(USB_Out_Buffer,64); if(numBytesRead != 0) { BYTE i; #ifdef NETV #else for(i=0;i<numBytesRead;i++) { USB_In_Buffer[i] = USB_Out_Buffer[i]; } //Test: Send SPI word to control motor if(USB_In_Buffer[0] == 'u') { motor_speed += 250; if(motor_speed > 3000) motor_speed = 3000; SpiChnPutC(4, motor_speed); } else if(USB_In_Buffer[0] == 'i') { motor_speed -= 250; if(motor_speed < -3000) motor_speed = -3000; SpiChnPutC(4, motor_speed); } putUSBUSART(USB_In_Buffer,numBytesRead); //Echo HBLED1 ^= 1; //Toggle LEDs HBLED2 ^= 1; #endif } } // Service the USB CDC driver CDCTxService(); } // End ProcessIO
void SPIAccelWriteToReg(int address, int data) { PORTFCLR = BIT_12; SpiChnPutC(SPI_CHANNEL4, address); SpiChnGetC(SPI_CHANNEL4); SpiChnPutC(SPI_CHANNEL4, data); SpiChnGetC(SPI_CHANNEL4); PORTFSET = BIT_12; }
int SPIAccelRead(int address) { int reading; PORTFCLR = BIT_12; SpiChnPutC(SPI_CHANNEL4, 0x80 + address); reading = SpiChnGetC(SPI_CHANNEL4); SpiChnPutC(SPI_CHANNEL4, 0xFF); reading = SpiChnGetC(SPI_CHANNEL4); PORTFSET = BIT_12; return reading; }
/* PmodDA2Send ** ** Synopsis: ** sends a 16 bit value from the PmodDA2 ** ** Input: SpiChannel chn - spi channel ** uint_16 data - the digital representation of the analog ** signal to send to the PmodDA2 ** ** Returns: none ** ** Errors: none */ void PmodDA2Send(SpiChannel chn, uint16_t data) { uint8_t dataPartA, dataPartB; dataPartB = data; dataPartA = data >> 8; PmodSPISetSSLow(chn); SpiChnPutC(chn,dataPartA); SpiChnGetC(chn); SpiChnPutC(chn,dataPartB); SpiChnGetC(chn); PmodSPISetSSHigh(chn); }
void MySPI_PutC(unsigned int theData) { int theDummyData; SpiChnPutC(SPI_CHANNEL1A, theData); theDummyData = SpiChnGetC(SPI_CHANNEL1A); }
/********************************************************************* * Function: int SpiDoLoopbackExample(SpiChannel chn, int nWords) * * PreCondition: None * * Input: chn - the SPI channel to use * nWords - number of words to transmit and receive for this test * * Output: 1 (true) if the SPI loopback transfer succeeded, * 0 (false) otherwise * * Side Effects: None * * Overview: Examples for the usage of the SPI Peripheral Lib for in a simple loopback mode * * Note: This test assumes that the SPI SDO output is connected to the SDI input. ********************************************************************/ int SpiDoLoopbackExample(SpiChannel chn, int nWords) { SpiInitDevice(chn, 1, 0, 0); // initialize the SPI channel as master, no frame mode while(nWords--) { unsigned short txData, rxData; txData=(unsigned short)rand(); SpiChnPutC(chn, txData); // send data rxData=SpiChnGetC(chn); // retreive the received data if(rxData!=txData) { return 0; } } return 1; }
unsigned int MySPI_GetC(void) { int theData; SpiChnPutC(SPI_CHANNEL1A, 0x00); theData = SpiChnGetC(SPI_CHANNEL1A); return(theData); }
unsigned int MySPI_PutGetC(unsigned int theDataIn) { int theDataOut; SpiChnPutC(SPI_CHANNEL1A, theDataIn); theDataOut = SpiChnGetC(SPI_CHANNEL1A); return(theDataOut); }
/********************************************************************* * Function: BYTE SSTGet4(void) * * PreCondition: none * * Input: None * * Output: none * * Side Effects: none * * Overview: Following routine reads bytes from the SST Flash and returns * * * Note: **********************************************************************/ BYTE SPIGet4(void) { BYTE data; SpiChnPutC(SPI_CHANNEL4, 0x00); data = SpiChnGetC(SPI_CHANNEL4); return data; }
void glcd_spi_write(uint8_t c) { GLCD_SELECT(); SpiChnPutC(SPI_CHANNEL2, c); // Wait until the byte is sent before deselecting while(SpiChnIsBusy(SPI_CHANNEL2)); GLCD_DESELECT(); }
/* clear_reg_7366(): Clears the given register */ void clear_reg_7366(int module, int reg) { char ReadData; char ir = (reg << 3); //Instruction ss_low(module); delay(); //Setup time SpiChnPutC(SPICHN, ir); //Write instruction after TX buffer empty while(SpiChnRxBuffFull(SPICHN)==0); //Wait for RX buffer full ReadData = SpiChnGetC(SPICHN); //Read what was clocked in during last write (nothing) ss_high(module); }
unsigned char spi_send_read_byte(unsigned char byte) { unsigned short txData, rxData; // transmit, receive characters int chn = 1; // SPI channel to use (1 or 2) txData = byte; // take inputted byte and store into txData SpiChnPutC(chn, txData); // send data rxData = SpiChnGetC(chn); // retreive over channel chn the received data into rxData return rxData; }
void __ISR(_SPI_2_VECTOR, ipl4) SPI2InterruptHandler(void) { static UINT ptrIndex = 0; static BOOL toggleData = TRUE; SpiChnPutC(SPI_CHANNEL2, (toggleData ? txBuffer[ptrIndex].leftChannel : txBuffer[ptrIndex++].rightChannel)); toggleData = !toggleData; if (ptrIndex >= FRAME_SIZE) ptrIndex = 0; INTClearFlag(INT_SPI2TX); }
void ADF_XMit(unsigned char ucByte,unsigned char *pData) { SpiChnPutC(SPI_CHANNEL1, ucByte); /*SEND_SPI(ucByte); // Send byte WAIT_SPI_RX; // wait for data received status bit*/ if(pData) *pData = SpiChnGetC(SPI_CHANNEL1); else (void)SpiChnGetC(SPI_CHANNEL1); }
int16_t motor_command(int16_t command) { unsigned int config = SPI_CON_MODE16 | SPI_CON_MSTEN | SPI_CON_CKE; // the last number is the clock divider SpiChnOpen(SPI_CHANNEL2, config, 256); //256 works // 4 doesn't //8 doesn't //16 doesn't //32 doesn't //64 doesn't //128 doesn't MDBSS = 0; waitabit(WAIT_TIME); SpiChnPutC(2, command); int16_t velocity = SpiChnGetC(2); MDBSS = 1; SpiChnClose(SPI_CHANNEL2); return velocity; }
/***************************************************************************** * CONFIG_3909() * * This function configures the MCP3909 to transmit data from its two * A/D converters to the PIC32 via the SPI port *****************************************************************************/ void CONFIG_3909() { DBPRINTF("CONFIG_3909...\n"); // SPI mode code int code = 0xA4; // set CS high mPORTDSetBits(BIT_9); // set MCLR low mPORTEClearBits(BIT_0); // delay DelayMs(5); // set MCLR high mPORTESetBits(BIT_0); // set CS low mPORTDClearBits(BIT_9); // feed SPI mode code to MCP3909 SpiChnPutC(1, code); DelayMs(1000); SpiChnPutC(1, 0x12345678); int data; data = getcSPI1(); char a = (char)data; char * c; c = &a; DBPUTC(c); data = getcSPI1(); a = (char)data; c = &a; DBPUTC(c); }
// write an individal command to the LCD void LcdWrite(unsigned char dc, unsigned char data) { if(dc) { mDC_High(); } else { mDC_Low(); } mSCE_Low(); SpiChnPutC(SPI_CHANNEL2, data); while(SpiChnGetStatus(SPI_CHANNEL2) & SPI_STAT_SPIBUSY); //mSCE_High(); }
// Initializes SPI communications void SPIAccelInit() { int garbage; SpiChnOpen(SPI_CHANNEL4, SPI_OPEN_MSTEN | SPI_OPEN_CKP_HIGH | SPI_OPEN_ENHBUF, 2); SpiChnPutC(SPI_CHANNEL4, 0x80); garbage = SpiChnGetC(SPI_CHANNEL4); SPIAccelWriteToReg(0x2C, 0x0A); SPIAccelWriteToReg(0x2D, 0x08); }
int main(void) { initPic32(); PORTSetPinsDigitalIn(IOPORT_A, BIT_0); PORTSetPinsDigitalIn(IOPORT_A, BIT_1); PORTSetPinsDigitalIn(IOPORT_B, BIT_14); PPSInput(1, SS1, RPA0); PPSInput(2, SDI1, RPA1); #ifndef NO_SDO PPSOutput(3, RPA2, SDO1); #endif SpiChnOpen(1, SPI_OPEN_MODE8|SPI_OPEN_SLVEN|SPI_OPEN_SSEN #ifdef NO_SDO |SPI_OPEN_DISSDO #endif , 2); init(); uint8_t lastByteReceived = 0; uint8_t cmd[8]; uint8_t length=0; uint8_t toRead = 1; while(1) { if(SpiChnTxBuffEmpty(1)) SpiChnPutC(1, lastByteReceived); lastByteReceived = 0; while(!SpiChnDataRdy(1)) loop(); uint8_t byte = SpiChnGetC(1); cmd[length++] = byte; toRead--; if(toRead==0) toRead = commandReceived(cmd, length); } }
void send(uint8_t* data, uint8_t len) { for(int i=0; i<len; i++) { SpiChnPutC(1, data[i]); SpiChnGetC(1); } }
uint8_t SPITransceve(uint8_t b){ SpiChnPutC(2, b); // send data on the master channel, SPI1 Delay1us(10); return SpiChnGetC(2); // get the received data }
/********************************************************************* * Function: void SPIPut4 (BYTE v) * * PreCondition: none * * Input: BYTE data * * Output: none * * Side Effects: none * * Overview: Following routine writes to flash * * * Note: **********************************************************************/ void SPIPut4(BYTE v) { BYTE tmp; SpiChnPutC(SPI_CHANNEL4, v); tmp = SpiChnGetC(SPI_CHANNEL4); }
/********************************************************************* * Function: int SpiDoMasterSlaveExample(int nCycles) * * PreCondition: None * * Input: nCycles - number of repeated transfers * * Output: 1 (true) if the SPI transfer succeeded, * 0 (false) otherwise * * Side Effects: None * * Overview: Examples for the usage of the SPI Peripheral Lib for in a simple master/slave transfer mode * * Note: This test uses both SPI channels. * The master channel (SPI1) sends data to a slave device (SPI2). * The slave device relays data back to the master. * This way we can verify that the connection to the slave is ok. * Hardware connections have to be made: * - SCK1 <-> SCK2 * - SDO1 <-> SDI2 * - SDI1 <-> SDO2 * - SS1 <-> SS2 (needed only if we use the framed mode) * ********************************************************************/ int SpiDoMasterSlaveExample(int nCycles) { int fail=0; // overall result SpiInitDevice(SPI_CHANNEL1, 1, 1, 1); // initialize the SPI channel 1 as master, frame master SpiInitDevice(SPI_CHANNEL2, 0, 1, 0); // initialize the SPI channel 2 as slave, frame slave while(nCycles-- && !fail) { unsigned int txferSize; unsigned short* pTxBuff; unsigned short* pRxBuff; txferSize=MIN_SPI_TXFER_SIZE+rand()%(MAX_SPI_TXFER_SIZE-MIN_SPI_TXFER_SIZE+1); // get a random transfer size pTxBuff=(unsigned short*)malloc(txferSize*sizeof(short)); pRxBuff=(unsigned short*)malloc(txferSize*sizeof(short)); // we'll transfer 16 bits words if(pTxBuff && pRxBuff) { unsigned short* pSrc=pTxBuff; unsigned short* pDst=pRxBuff; int ix; int rdData; for(ix=0; ix<txferSize; ix++) { pTxBuff[ix]=(unsigned short)rand(); // fill buffer with some random data } ix=txferSize+1; // transfer one extra word to give the slave the possibility to reply back the last sent word while(ix--) { SpiChnPutC(1, *pSrc++); // send data on the master channel, SPI1 rdData=SpiChnGetC(1); // get the received data if(ix!=txferSize) { // skip the first received character, it's garbage *pDst++=rdData; // store the received data } rdData=SpiChnGetC(2); // receive data on the slave channel, SPI2 SpiChnPutC(2, rdData); // relay back data } // now let's check that the data was received ok pSrc=pTxBuff; pDst=pRxBuff; for(ix=0; ix<txferSize; ix++) { if(*pDst++!=*pSrc++) { fail=1; // data mismatch break; } } } else { // memory allocation failed fail=1; } free(pRxBuff); free(pTxBuff); // free the allocated buffers } return !fail; }
int main(void) { SpiOpenFlags spiFlags; AudioStereo test_sine[]={ 0 , 0 , 946234 , 946234 , 1877546 , 1877546 , 2779247 , 2779247 , 3637119 , 3637119 , 4437630 , 4437630 , 5168158 , 5168158 , 5817180 , 5817180 , 6374462 , 6374462 , 6831216 , 6831216 , 7180237 , 7180237 , 7416020 , 7416020 , 7534850 , 7534850 , 7534850 , 7534850 , 7416020 , 7416020 , 7180237 , 7180237 , 6831216 , 6831216 , 6374462 , 6374462 , 5817180 , 5817180 , 5168158 , 5168158 , 4437630 , 4437630 , 3637119 , 3637119 , 2779247 , 2779247 , 1877546 , 1877546 , 946234 , 946234 , 0 , 0 , -946234 , -946234 , -1877546 , -1877546 , -2779247 , -2779247 , -3637119 , -3637119 , -4437630 , -4437630 , -5168158 , -5168158 , -5817180 , -5817180 , -6374462 , -6374462 , -6831216 , -6831216 , -7180237 , -7180237 , -7416020 , -7416020 , -7534850 , -7534850 , -7534850 , -7534850 , -7416020 , -7416020 , -7180237 , -7180237 , -6831216 , -6831216 , -6374462 , -6374462 , -5817180 , -5817180 , -5168158 , -5168158 , -4437630 , -4437630 , -3637119 , -3637119 , -2779247 , -2779247 , }; // Initialize audio codec. WM8960CodecOpen(); WM8960CodecConfigVolume(0,0); WM8960CodecConfigSampleRate(SAMPLE_RATE_16000_HZ); WM8960CodecConfigVolume(volADC,volDAC); //Congigure MIPS, Prefetch Cache module. SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); INTEnableSystemMultiVectoredInt(); //Test tone vector sampled at 48kHz. txBuffer = test_sine; //Configure the direction of used pins and //configure as digital pins. PORTSetPinsDigitalIn(IOPORT_G, BIT_7); PORTSetPinsDigitalOut(IOPORT_G, BIT_6); PORTSetPinsDigitalOut(IOPORT_G, BIT_8); PORTSetPinsDigitalOut(IOPORT_G, BIT_9); // //Configure Reference Clock Output to 12.288MHz. // mOSCREFOTRIMSet(REFTRIM); // OSCREFConfig(OSC_REFOCON_USBPLL, //USB-PLL clock output used as REFCLKO source // OSC_REFOCON_OE | OSC_REFOCON_ON, //Enable and turn on the REFCLKO // RODIV); //Configure SPI in I2S mode with 24-bit stereo audio. spiFlags= SPI_OPEN_MSTEN | //Master mode enable SPI_OPEN_SSEN | //Enable slave select function SPI_OPEN_CKP_HIGH | //Clock polarity Idle High Actie Low SPI_OPEN_MODE32 | //Data mode: 32b SPI_OPEN_FRMEN | // Enable Framed SPI SPI_OPEN_FSP_IN | // Frame Sync Pulse is input SPI_OPEN_FSP_HIGH; //Frame Sync Pulse is active high //Configure and turn on the SPI1 module. SpiChnEnable(WM8960DRV_SPI_MODULE, FALSE); SpiChnConfigure(WM8960DRV_SPI_MODULE, spiFlags); SpiChnSetBitRate(WM8960DRV_SPI_MODULE, GetPeripheralClock(), 1024000); SpiChnEnable(WM8960DRV_SPI_MODULE, TRUE); //Enable SPI2 interrupt. INTSetVectorPriority(INT_SPI_2_VECTOR, INT_PRIORITY_LEVEL_4); INTSetVectorSubPriority(INT_SPI_2_VECTOR, INT_SUB_PRIORITY_LEVEL_0); INTEnable(INT_SPI2, INT_ENABLED); SpiChnPutC(SPI_CHANNEL2, 0); //Dummy write to start the SPI //while (1); return 0; }