00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00028 /* ---------------------------------------------------------------------------- */ 00029 00030 /** 00031 * \page twi_slave TWI Slave Example 00032 * 00033 * \section Purpose 00034 * 00035 * This project demonstrates the TWI peripheral in slave mode. It mimics the 00036 * behavior of a serial memory, enabling the TWI master to read and write 00037 * data in its internal SRAM. 00038 * 00039 * \section Requirements 00040 * 00041 * This package can be used with SAM V71 Xplained Ultra board or SAME70 Xplained board. 00042 * 00043 * \section Description 00044 * 00045 * After launching the program, the device will act as a simple TWI-enabled 00046 * serial memory containing 256 bytes. This enables this project to be used 00047 * with the twi_eeprom project as the master after modifying the slave address 00048 * AT24MAC_ADDRESS as 0x53 in main.c. 00049 * 00050 * To write in the memory, the TWI master must address the device first, then 00051 * send one byte containing the memory address to access. Additional bytes are 00052 * treated as the data to write. 00053 * 00054 * Reading is done in the same fashion, except that after receiving the memory 00055 * address, the device will start outputting data until a STOP condition is 00056 * sent by the master. 00057 * 00058 * Please connect the two SAMV71/SAME70 boards with the following pins which could be 00059 * easily wired from the board. 00060 * - <b>SAMV71/SAME70 -- SAMV71/SAME70</b> 00061 * - TWD0(PA03,PIN11 of EXT1 ) -- TWD0(PA03,PIN11 of EXT1 ) 00062 * - TWCK0(PA04,PIN12 of EXT1) -- TWCK0(PA04,PIN12 of EXT1) 00063 * - GND -- GND 00064 * \section Usage 00065 * 00066 * -# Build the program and download it inside the board. 00067 * Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf 00068 * -# On the computer, open and configure a terminal application 00069 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00070 * - 115200 baud rate 00071 * - 8 bits of data 00072 * - No parity 00073 * - 1 stop bit 00074 * - No flow control 00075 * -# Start the application. 00076 * -# In the terminal window, the following text should appear (values depend 00077 * on the board and chip used): 00078 * \code 00079 * -- TWI Slave Example xxx -- 00080 * -- SAMxxxxx-xx 00081 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00082 * -I- Configuring the TWI in slave mode 00083 * \endcode 00084 * -# For the TWI Master board, see the description inside his project 00085 * -# and the "Master" board will output: 00086 * \code 00087 * -- TWI EEPROM Example xxx -- 00088 * -- SAMxxxxx-xx 00089 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00090 * -I- Filling page #0 with zeroes ... 00091 * -I- Filling page #1 with zeroes ... 00092 * ...... 00093 * -I- 0 comparison error(s) found 00094 * ...... 00095 * -I- 0 comparison error(s) found 00096 * \endcode 00097 * 00098 * \section References 00099 * - twi_slave/main.c 00100 * - twi_eeprom/main.c 00101 * - twi.c 00102 * - twid.h 00103 */ 00104 00105 /** 00106 * \file 00107 * 00108 * This file contains all the specific code for the twi_slave example. 00109 */ 00110 00111 /*---------------------------------------------------------------------------- 00112 * Headers 00113 *----------------------------------------------------------------------------*/ 00114 00115 #include "board.h" 00116 00117 #include <stdio.h> 00118 #include <string.h> 00119 00120 /*---------------------------------------------------------------------------- 00121 * Local definitions 00122 *----------------------------------------------------------------------------*/ 00123 /** Slave address of the device on the TWI bus. */ 00124 #define SLAVE_ADDRESS 0x53 00125 00126 /** Memory size in bytes (example AT24C512)*/ 00127 #define MEMORY_SIZE 256 00128 00129 /** Eeprom Pins definition */ 00130 #define BOARD_PINS_TWI_SLAVE PINS_TWI0 00131 /** TWI0 peripheral ID for eeprom device*/ 00132 #define BOARD_ID_TWI_EEPROM ID_TWIHS0 00133 /** TWI0 base address for eeprom device */ 00134 #define BOARD_BASE_TWI_SLAVE TWIHS0 00135 00136 /*---------------------------------------------------------------------------- 00137 * Local variables 00138 *----------------------------------------------------------------------------*/ 00139 /** Pio pins to configure. */ 00140 const Pin pins[] = BOARD_PINS_TWI_SLAVE; 00141 00142 /** The slave device instance*/ 00143 typedef struct _SlaveDeviceDriver 00144 { 00145 /** PageAddress of the slave device*/ 00146 uint16_t pageAddress; 00147 /** Offset of the memory access*/ 00148 uint16_t offsetMemory; 00149 /** Read address of the request*/ 00150 uint8_t acquireAddress; 00151 /** Memory buffer*/ 00152 uint8_t pMemory[MEMORY_SIZE]; 00153 } SlaveDeviceDriver; 00154 00155 static SlaveDeviceDriver EmulateDriver; 00156 00157 /*---------------------------------------------------------------------------- 00158 * Local functions 00159 *----------------------------------------------------------------------------*/ 00160 /** 00161 * \brief Interrupt handler for the TWI slave. 00162 */ 00163 /** 00164 * \brief TWI interrupt handler. Forwards the interrupt to the TWI driver handler. 00165 */ 00166 void TWIHS0_Handler( void ) 00167 { 00168 volatile uint32_t status; 00169 00170 status = TWI_GetStatus( BOARD_BASE_TWI_SLAVE); 00171 if (((status & TWIHS_SR_SVACC) == TWIHS_SR_SVACC)) { 00172 if (EmulateDriver.acquireAddress == 0) { 00173 TWI_DisableIt(BOARD_BASE_TWI_SLAVE, TWIHS_IDR_SVACC); 00174 TWI_EnableIt(BOARD_BASE_TWI_SLAVE, TWIHS_IER_RXRDY 00175 | TWIHS_IER_EOSACC 00176 | TWIHS_IER_SCL_WS ); 00177 EmulateDriver.acquireAddress++; 00178 EmulateDriver.pageAddress = 0; 00179 EmulateDriver.offsetMemory = 0; 00180 } 00181 00182 if ((status & TWIHS_SR_GACC) == TWIHS_SR_GACC) { 00183 printf("General Call Treatment\n\r"); 00184 printf("not treated"); 00185 } else { 00186 if ((status & TWIHS_SR_SVREAD) == TWIHS_SR_SVREAD) { 00187 /*Slave Read */ 00188 if (((status & TWIHS_SR_TXRDY) == TWIHS_SR_TXRDY) 00189 && ((status & TWIHS_SR_NACK) == 0)) { 00190 if ((EmulateDriver.acquireAddress == 2)) { 00191 /* Write one byte of data from slave to master device */ 00192 TWI_WriteByte( BOARD_BASE_TWI_SLAVE, 00193 EmulateDriver.pMemory[EmulateDriver.pageAddress 00194 + EmulateDriver.offsetMemory]); 00195 EmulateDriver.offsetMemory++; 00196 } 00197 } 00198 } else { 00199 /*Slave Write*/ 00200 if ((status & TWIHS_SR_RXRDY) == TWIHS_SR_RXRDY) { 00201 if (EmulateDriver.acquireAddress == 1) { 00202 /* Acquire MSB address */ 00203 EmulateDriver.pageAddress = (TWI_ReadByte(BOARD_BASE_TWI_SLAVE) & 0xFF); 00204 EmulateDriver.acquireAddress++; 00205 } else { 00206 /* Read one byte of data from master to slave device */ 00207 EmulateDriver.pMemory[EmulateDriver.pageAddress + EmulateDriver.offsetMemory] 00208 = (TWI_ReadByte(BOARD_BASE_TWI_SLAVE) & 0xFF); 00209 EmulateDriver.offsetMemory++; 00210 } 00211 } 00212 } 00213 } 00214 } else { 00215 if ((status & TWIHS_SR_EOSACC) == TWIHS_SR_EOSACC) { 00216 if ((status & TWIHS_SR_TXCOMP) == TWIHS_SR_TXCOMP) { 00217 /* End of transfer, end of slave access */ 00218 EmulateDriver.offsetMemory = 0; 00219 EmulateDriver.acquireAddress = 0; 00220 EmulateDriver.pageAddress = 0; 00221 TWI_EnableIt( BOARD_BASE_TWI_SLAVE, TWIHS_SR_SVACC); 00222 TWI_DisableIt( BOARD_BASE_TWI_SLAVE, TWIHS_IDR_RXRDY 00223 | TWIHS_IDR_EOSACC 00224 | TWIHS_IDR_SCL_WS ); 00225 } 00226 } 00227 } 00228 } 00229 00230 /*---------------------------------------------------------------------------- 00231 * Global functions 00232 *----------------------------------------------------------------------------*/ 00233 00234 /** 00235 * \brief Application entry point for TWI slave example. 00236 * 00237 * \return Unused (ANSI-C compatibility). 00238 */ 00239 int main(void) 00240 { 00241 uint32_t i; 00242 00243 /* Disable watchdog */ 00244 WDT_Disable(WDT); 00245 00246 /* Enable I and D cache */ 00247 SCB_EnableICache(); 00248 SCB_EnableDCache(); 00249 00250 PIO_Configure(pins, PIO_LISTSIZE(pins)); 00251 00252 printf("-- TWI Slave Example %s --\n\r", SOFTPACK_VERSION); 00253 printf("-- %s\n\r", BOARD_NAME); 00254 printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); 00255 00256 /* Enable TWI peripheral clock */ 00257 PMC_EnablePeripheral(BOARD_ID_TWI_EEPROM); 00258 00259 for (i = 0; i < MEMORY_SIZE; i++) 00260 EmulateDriver.pMemory[i] = 0; 00261 00262 EmulateDriver.offsetMemory = 0; 00263 EmulateDriver.acquireAddress = 0; 00264 EmulateDriver.pageAddress = 0; 00265 00266 /* Configure TWI as slave */ 00267 printf( "-I- Configuring the TWI in slave mode\n\r" ); 00268 TWI_ConfigureSlave(BOARD_BASE_TWI_SLAVE, SLAVE_ADDRESS); 00269 00270 /* Clear receipt buffer */ 00271 TWI_ReadByte(BOARD_BASE_TWI_SLAVE); 00272 00273 printf("TWI is in slave mode\n\r"); 00274 00275 /* Configure TWI interrupts */ 00276 NVIC_ClearPendingIRQ(TWIHS0_IRQn); 00277 NVIC_EnableIRQ(TWIHS0_IRQn); 00278 00279 TWI_EnableIt(BOARD_BASE_TWI_SLAVE, TWIHS_SR_SVACC); 00280 00281 while (1) { 00282 } 00283 } 00284 00285