- /*
- * Copyright (c) 2021, Texas Instruments Incorporated
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of Texas Instruments Incorporated nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "ti_msp_dl_config.h"
- /* Maximum size of TX packet */
- #define I2C_TX_MAX_PACKET_SIZE (16)
- /* Maximum size of RX packet */
- #define I2C_RX_MAX_PACKET_SIZE (16)
- /* Commands for the ADC sampling */
- #define SAMPLE_ADC (0x01)
- #define SEND_RESULTS (0x02)
- #define SAMPLE_SEND_RESULTS (0x03)
- /* Data sent to Controller in response to Read transfer, default set to 0xAA */
- uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE] = {0xAA};
- /* Counters for TX length and bytes sent */
- uint32_t gTxLen, gTxCount;
- /* Data received from Controller during a Write transfer */
- uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];
- /* Counters for TX length and bytes sent */
- uint32_t gRxLen, gRxCount, gCommandCount;
- /* Boolean to know when a stop command was issued */
- bool gStopReceived = false;
- /* ADC variables:
- * gADCResult is the adc result taken from the Memory Register
- * NumberOfADCSamples is the count of total ADC samples to keep track for the gTxResult buffer
- */
- uint16_t gADCResult;
- uint8_t gNumberOfADCSamples = 0;
- bool gCheckADC = false;
- /* Process Command will take the command from the I2C Rx and parse which command is to be issued */
- void processCommand(uint8_t cmd);
- /* ADC Process will start the ADC and separate the ADC result into 8 bits to place into the Tx Packet buffer. */
- void ADCProcess();
- int main(void)
- {
- SYSCFG_DL_init();
- /* Set LED to indicate start of transfer */
- DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
- /* Reset variables for the Tx, these are used in the I2C ISR */
- gTxCount = 0;
- gTxLen = 0;
- DL_I2C_enableInterrupt(I2C_INST, DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);
- /* Initialize variables to receive data inside RX ISR */
- gRxCount = 0;
- gRxLen = I2C_RX_MAX_PACKET_SIZE;
- NVIC_EnableIRQ(I2C_INST_INT_IRQN);
- NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
- while (1)
- {
- /* Sleep until the stop command is given from the I2C Controller */
- while(gStopReceived == false)
- __WFE();
- gStopReceived = false;
- /* Process given commands */
- for(uint16_t i = 0; i < gCommandCount; i++){
- processCommand(gRxPacket[i]);
- }
- gCommandCount = 0;
- }
- }
- /* Process the command given */
- void processCommand(uint8_t cmd){
- switch(cmd){
- /* Sample the ADC */
- case SAMPLE_ADC:
- ADCProcess();
- break;
- /* Add 2 to the Tx Length, this equates to one more full result added to the TX transmission */
- case SEND_RESULTS:
- gTxLen += 2;
- break;
- /* Sample the ADC and increment the Tx Length. */
- case SAMPLE_SEND_RESULTS:
- ADCProcess();
- gTxLen += 2;
- break;
- default:
- break;
- }
- }
- /* Start the ADC process of sampling and storing into the TxPacket Buffer */
- void ADCProcess(){
- /* Start the ADC Sampling */
- DL_ADC12_startConversion(ADC12_0_INST);
- /* Sleep until the ADC sampling and conversion is finished, then reset the boolean */
- while(gCheckADC == false){
- __WFI();
- }
- gCheckADC = false;
- /* Get the ADC result and place the upper byte and lower byte into the TxPacket, upper byte first */
- gADCResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
- gTxPacket[gNumberOfADCSamples*2] = (uint8_t)((gADCResult >> 8) & 0xFF);
- gTxPacket[gNumberOfADCSamples*2 + 1] = (uint8_t)(gADCResult & 0xFF);
- /* Make sure the number of ADC samples does not go over the TxPacket size, if it does next sample will overwrite */
- gNumberOfADCSamples++;
- if(gNumberOfADCSamples*2 + 1 > I2C_TX_MAX_PACKET_SIZE)
- {
- gNumberOfADCSamples = 0;
- }
- DL_ADC12_enableConversions(ADC12_0_INST);
- }
- void ADC12_0_INST_IRQHandler(void) {
- switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
- case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
- gCheckADC = true;
- break;
- default:
- break;
- }
- }
- void I2C_INST_IRQHandler(void)
- {
- static bool commandReceived = false;
- switch (DL_I2C_getPendingInterrupt(I2C_INST)) {
- case DL_I2C_IIDX_TARGET_START:
- /* Initialize RX or TX after Start condition is received */
- gTxCount = 0;
- gRxCount = 0;
- commandReceived = false;
- /* Flush TX FIFO to refill it */
- DL_I2C_flushTargetTXFIFO(I2C_INST);
- break;
- case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
- /* Store received commands in buffer */
- commandReceived = true;
- while (DL_I2C_isTargetRXFIFOEmpty(I2C_INST) != true) {
- if (gRxCount < gRxLen) {
- gRxPacket[gRxCount++] = DL_I2C_receiveTargetData(I2C_INST);
- } else {
- /* Prevent overflow and just ignore data */
- DL_I2C_receiveTargetData(I2C_INST);
- }
- }
- break;
- case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
- /* Fill TX FIFO with ADC Results */
- if (gTxCount < gTxLen) {
- gTxCount += DL_I2C_fillTargetTXFIFO(
- I2C_INST, &gTxPacket[gTxCount], (gTxLen - gTxCount));
- } else {
- /*
- * Fill FIFO with 0xAA if more data is requested than
- * expected gTxLen
- */
- while (DL_I2C_transmitTargetDataCheck(I2C_INST, 0xAA) != false)
- ;
- }
- break;
- case DL_I2C_IIDX_TARGET_STOP:
- /* If commands were received, set the command count to RxCount and reset fifo */
- if (commandReceived == true) {
- gCommandCount = gRxCount;
- commandReceived = false;
- DL_I2C_flushTargetTXFIFO(I2C_INST);
- }
- /* Set Stop Received to true to allow the main loop to proceed */
- gStopReceived = true;
- /* Toggle LED to indicate successful RX or TX */
- DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
- break;
- default:
- break;
- }
- }
|