Init function is fully implmented. I2C Start condition is working, curretnly struggling how to send to the slave the register no that we want to read from

i2c
key 3 years ago
parent ec2a90186e
commit e1c061bd1f

@ -100,6 +100,7 @@ typedef enum{
typedef enum typedef enum
{ {
i2cNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */ i2cNotInitialized, /*!< Default Peripheral is not yet Initialized **DEFAULT** */
i2cInitialized, /*!< I2C CHannle is initilized but not neceserly ready */
i2cReady, /*!< Peripheral Initialized and ready for use */ i2cReady, /*!< Peripheral Initialized and ready for use */
i2cBusy, /*!< An internal process is ongoing */ i2cBusy, /*!< An internal process is ongoing */
i2cTransmitting, /*!< Data Transmission process is ongoing */ i2cTransmitting, /*!< Data Transmission process is ongoing */
@ -139,13 +140,13 @@ typedef struct i2c_t
/** /**
* @brief Initilize the I2C Hardware * @brief Initilize the I2C Hardware
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cInit(i2c_t *i2cHardware); void i2cInit(i2c_t *i2cHardware);
/** /**
* @brief De-Initilize the I2C Hardware * @brief De-Initilize the I2C Hardware
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cDeInit(i2c_t *i2cHardware); void i2cDeInit(i2c_t *i2cHardware);
@ -158,7 +159,7 @@ void i2cSetMode(i2c_t *i2cHardware, i2cMode_t mode);
/** /**
* @brief Set the i2c channles mode as Master Slave or Multymaster * @brief Set the i2c channles mode as Master Slave or Multymaster
* @param channel is the i2c hardware channel * @param i2cHardware is the i2c hardware channel
* @param size Is the Adress isze to be used 7 Bit or 10 Bit * @param size Is the Adress isze to be used 7 Bit or 10 Bit
* @param addressOne The forst address for the device * @param addressOne The forst address for the device
* @param addressTwo The second address for the device only if dual address mode is not defined * @param addressTwo The second address for the device only if dual address mode is not defined
@ -167,14 +168,14 @@ void i2cSetAddress(i2c_t *i2cHardware, i2cAddressSize_t size, uint16_t addressOn
/** /**
* @brief Stets the Communication speed * @brief Stets the Communication speed
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param speed the different awailable speeds * @param speed the different awailable speeds
*/ */
void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed); void i2cSetSpeed(i2c_t *i2cHardware, i2cSpeed_t speed);
/** /**
* @brief Initiates the opperation mode for the selected i2c Channel * @brief Initiates the opperation mode for the selected i2c Channel
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes * @param opperation define if the i2c channel will opperate on pollin, Interrupt, or DMA modes
*/ */
void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation); void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
@ -182,21 +183,21 @@ void i2cSetOpperation(i2c_t *i2cHardware, i2cOpperationMode_t opperation);
/** /**
* @brief Sets the finetuning of the Timings for the communication some standards as * @brief Sets the finetuning of the Timings for the communication some standards as
* SMBUS have different timing requirements * SMBUS have different timing requirements
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param The value to be written in the register. This will heavily depend on the hardware * @param The value to be written in the register. This will heavily depend on the hardware
*/ */
void i2cSetTimings(i2c_t *i2cHardware, uint32_t timing); void i2cSetTimings(i2c_t *i2cHardware, uint32_t timing);
/** /**
* @brief Set the wakeup mode * @brief Set the wakeup mode
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param wake the desider wakeup mode for now i have found only one mode. * @param wake the desider wakeup mode for now i have found only one mode.
*/ */
void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake); void i2cSetWakeup(i2c_t *i2cHardware, i2cWakeUpTypes_t wake);
/** /**
* @brief Set the timeout to close the i2c wait time if a communication fails. * @brief Set the timeout to close the i2c wait time if a communication fails.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param timeout the desider timeout duration in ticks. * @param timeout the desider timeout duration in ticks.
*/ */
void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout); void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
@ -204,13 +205,13 @@ void i2cSetTimeout(i2c_t *i2cHardware, uint8_t timeout);
/** /**
* @brief Resets the i2c Periferal to it's inital state. * @brief Resets the i2c Periferal to it's inital state.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cPeriferalReset(i2c_t *i2cHardware); void i2cPeriferalReset(i2c_t *i2cHardware);
/** /**
* @brief Resets the i2c to it's inital state. * @brief Resets the i2c to it's inital state.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cReset(i2c_t *i2cHardware); void i2cReset(i2c_t *i2cHardware);
@ -223,7 +224,7 @@ void i2cReset(i2c_t *i2cHardware);
* automaticaly choose between i2cMasterSend(); or i2cSlaveSend(); * automaticaly choose between i2cMasterSend(); or i2cSlaveSend();
* Depending if the I2C channel was initiated as slave or master. * Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data to be written * @param data is the data to be written
@ -236,7 +237,7 @@ void i2cWrite(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress
* automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve(); * automaticaly choose between i2cMasterRecieve(); or i2cSlaveRecieve();
* Depending if the I2C channel was initiated as slave or master. * Depending if the I2C channel was initiated as slave or master.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data which has been red * @param data is the data which has been red
@ -247,16 +248,16 @@ void i2cRead(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress,
/** /**
* @brief Recieve a Single Byte as master from from the given devices register. * @brief Recieve a Single Byte as master from from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
*/ */
void i2cMasterRecieve(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data); void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t *registerAddress, uint8_t *data);
/** /**
* @brief Sends a Single Byte as master to the given devices register. * @brief Sends a Single Byte as master to the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the send command will be sent * @param devAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device * @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent * @param data is the data to be sent
@ -266,7 +267,7 @@ void i2cMasterSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAd
/** /**
* @brief Recieve a Single Byte as slave from given devices register. * @brief Recieve a Single Byte as slave from given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
@ -276,13 +277,19 @@ void i2cSlaveRecieve(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *register
/** /**
* @brief Recieve a Single Byte as slave from the given devices register. * @brief Recieve a Single Byte as slave from the given devices register.
* this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA) * this function will adapt himself to the selected oppeartion mode (Polling / Int / DMA)
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
*/ */
void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data); void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data);
/**
* @brief Initiates a Start condition.
* @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/
void i2cSendStart(i2c_t *i2cHardware);
/************************************************************************************************** /**************************************************************************************************
I2C Communication functions Polling / Blocking Mode I2C Communication functions Polling / Blocking Mode
@ -290,7 +297,7 @@ void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAdd
/** /**
* @brief Recieve a Single Byte in polling mode as master from from the given devices register. * @brief Recieve a Single Byte in polling mode as master from from the given devices register.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
@ -298,7 +305,7 @@ void i2cSlaveSend(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAdd
void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data); void i2cMasterRecievePolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *registerAddress, uint8_t *data);
/** /**
* @brief Sends a Single Byte in polling mode as master to the given devices register. * @brief Sends a Single Byte in polling mode as master to the given devices register.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the send command will be sent * @param devAddress is the address of the device to which the send command will be sent
* @param registerAddress is the regiter to be written to the device * @param registerAddress is the regiter to be written to the device
* @param data is the data to be sent * @param data is the data to be sent
@ -307,7 +314,7 @@ void i2cMasterSendPolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *reg
/** /**
* @brief Recieve a Single Byte in polling mide as slave from the given devices register. * @brief Recieve a Single Byte in polling mide as slave from the given devices register.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
@ -316,7 +323,7 @@ void i2cSlaveRecievePolling(i2c_t *i2cHardware, uint16_t *devAddress, uint8_t *r
/** /**
* @brief Recieve a Single Byte in polling mode as slave from the given devices register. * @brief Recieve a Single Byte in polling mode as slave from the given devices register.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
* @param registerAddress is the regiter to be red from the device * @param registerAddress is the regiter to be red from the device
* @param data is the data whic has been red * @param data is the data whic has been red
@ -342,7 +349,7 @@ void i2cBusClear(); // I2C Standart : in case if SCL is stuck
* @brief This function will scan every for possible addresses to discover devices on the bus. * @brief This function will scan every for possible addresses to discover devices on the bus.
* And write them to the Devices list given to him. This function will not discover more * And write them to the Devices list given to him. This function will not discover more
* devices than what he is told. * devices than what he is told.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devices list where the discevered devices will be written * @param devices list where the discevered devices will be written
* @param deviceCount Max number of devices to be discovered. * @param deviceCount Max number of devices to be discovered.
*/ */
@ -351,7 +358,7 @@ void i2cDiscoverDevices(i2c_t *i2cHardware, uint16_t *devices, uint8_t deviceCou
/** /**
* @brief This function will try to communicate with a device with every speed * @brief This function will try to communicate with a device with every speed
* allowed by his hardware to find out the maximum communication sppeed possible. * allowed by his hardware to find out the maximum communication sppeed possible.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to which the read command will be sent * @param devAddress is the address of the device to which the read command will be sent
*/ */
i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *devAddress); i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *devAddress);
@ -359,14 +366,14 @@ i2cSpeed_t i2cTestDeviceSpeed(i2c_t *i2cHardware, uint16_t *devAddress);
/** /**
* @brief This function will read the device info register (if awailable) as follows : * @brief This function will read the device info register (if awailable) as follows :
* I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev. * I2c Standart : 3 Bytes (24 bits) | 12 Bits : Manufacturer info | 9 Bits: Part Identification | 3 Bits DIE Rev.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
* @param devAddress is the address of the device to be red * @param devAddress is the address of the device to be red
*/ */
uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *devAddress); uint32_t i2cReadDeviceInfo(i2c_t *i2cHardware, uint16_t *devAddress);
/** /**
* @brief The selected i2c channel is put on sleep. * @brief The selected i2c channel is put on sleep.
* @param channel is the beforehand declared i2c channel with his opperation modes * @param i2cHardware is the beforehand declared i2c channel with his opperation modes
*/ */
void i2cSleep(i2c_t *i2cHardware); void i2cSleep(i2c_t *i2cHardware);

@ -8,7 +8,6 @@
* @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips : * @brief I2C communitation based on the Standart I2C Protocol V7 Defined by NXP/Philips :
* following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA * following third Party Protocols based on I2C Bus are not going to be implemented : C-BUS SMBUS PMBUS IPMI DDC ATCA
* This will also not have a I3C support for the forseable futrue. This code is generated for the stm32f4xK6 series of mcu for stm * This will also not have a I3C support for the forseable futrue. This code is generated for the stm32f4xK6 series of mcu for stm
*
* *
* **Detailed Description :** * **Detailed Description :**
* *
@ -27,7 +26,42 @@
void i2cInit(i2c_t *i2cHardware) void i2cInit(i2c_t *i2cHardware)
{ {
i2cReset(i2cHardware); i2cReset(i2cHardware);
RCC->APB1ENR |= i2cBus_En_bitPos[i2cHardware->channelNo];
// Enables the i2c bus
RCC->APB1ENR |= (1 << i2cBus_En_bitPos[i2cHardware->channelNo]);
// Make sure that the periferal is disabled.
I2C_BASE->CR1 &= ~I2C_CR1_PE;
//Configure analog filter. Anlalog filter is on
I2C_BASE->CR1 &=~ I2C_CR1_ANFOFF;
//Configure the clock
I2C_BASE->TIMINGR = i2cHardware->timing;
//Configure NoStrech Streching mode is disabled (slave only)
I2C_BASE->CR1 |= I2C_CR1_NOSTRETCH;
//Automatic end mode (master mode) Enablede as default
I2C_BASE->CR2 |= I2C_CR2_AUTOEND;
if(i2cHardware->mode == i2cModeMaster)
{
if(i2cHardware->addressSize == i2cAddressSizeTenBits)
{
I2C_BASE->CR2 |= I2C_CR2_ADD10; // 10 Bit addressing
}
else
{
I2C_BASE->CR2 &= ~I2C_CR2_ADD10; // 7 Bit addressing DEFAULT
}
}
//activating the Perriferal.
I2C_BASE->CR1 |= I2C_CR1_PE;
i2cHardware->state = i2cInitialized;
} }
void i2cReset(i2c_t *i2cHardware) void i2cReset(i2c_t *i2cHardware)
@ -36,4 +70,48 @@ void i2cReset(i2c_t *i2cHardware)
RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]); RCC->APB1RSTR &= ~(1 << i2cBus_Rst_bitPos[i2cHardware->channelNo]);
} }
void i2cRead( i2c_t *i2cHardware,
uint16_t *devAddress,
uint8_t *registerAddress,
uint8_t *data,
uint8_t dataLenght)
{
i2cHardware->state = i2cBusy;
switch(i2cHardware->mode)
{
case i2cModeMaster: // Implement for loops for more than one byte.
i2cMasterRecieve(i2cHardware, devAddress, registerAddress, data);
break;
case i2cModeSlave:
i2cSlaveRecieve(i2cHardware, devAddress, registerAddress, data);
break;
case i2cModeMultyMaster:
// TO implement
break;
default:
i2cThrowError(1);
}
}
// this function still doesn't implment 10 bit oopeartion TODO
void i2cMasterRecieve(i2c_t *i2cHardware, uint8_t devAddress, uint8_t *registerAddress, uint8_t *data)
{
// Wait until no communication is ongoign
while(I2C_BASE->ISR & (I2C_ISR_BUSY));
i2cHardware->state = i2cRecieving;
//Slave address
I2C_BASE->CR2 |= devAddress << 1; // The bit no 0 is not taken in concideration in 7bit mode
//Read Mode
I2C_BASE->CR2 |= I2C_CR2_RD_WRN;
data = I2C_BASE->TXDR;
//Generate start condition
I2C_BASE->CR2 |= I2C_CR2_START;
//Wait until the start condition in generated.
while(!(I2C_BASE->ISR & (I2C_ISR_BUSY)));
}

@ -43,7 +43,10 @@ int main(int argc, char *argv[])
{ {
uint8_t i = 0; uint8_t i = 0;
uint8_t slaveAddress = 0xC0;
uint8_t registerToRead = 0x00;
uint8_t charTosend = 0;
char buffer [8];
// making array with all available timers // making array with all available timers
//timerNo_t timers[MAX_TIMER_CHANNEL_COUNT] = {timer_1, timer_2, timer_3, timer_14, timer_16, timer_17}; //timerNo_t timers[MAX_TIMER_CHANNEL_COUNT] = {timer_1, timer_2, timer_3, timer_14, timer_16, timer_17};
@ -68,7 +71,7 @@ int main(int argc, char *argv[])
//blinks 10 times to indicate the sicsessfull init if the device //blinks 10 times to indicate the sicsessfull init if the device
for(i = 0 ; i < 10 ; i++) { for(i = 0 ; i < 2 ; i++) {
delayMs(100); delayMs(100);
pinToggle(pinB3); pinToggle(pinB3);
delayMs(100); delayMs(100);
@ -98,29 +101,30 @@ int main(int argc, char *argv[])
i2c_1.wakeOn = i2cWakeUpDisabled; i2c_1.wakeOn = i2cWakeUpDisabled;
i2c_1.state = i2cNotInitialized; i2c_1.state = i2cNotInitialized;
print_Usart(usart2, "I2C init started\n\r");
i2cInit(&i2c_1); i2cInit(&i2c_1);
/* print_Usart(usart2, "I2C initialized\n\r");
for(i = 0 ; i < 20 ; i++) { print_Usart(usart2, "I2C_BASE->ISR & I2C_ISR_TXIS : ");
delayMs(50); i2cMasterRecieve(&i2c_1,slaveAddress,&registerToRead,&charTosend);
pinToggle(pinB3);
delayMs(50); buffer[0] = charTosend>>4; //4 MSB
} buffer[1] = charTosend& ((1 << 3)); //4 LSB
usartSendChar(usart2, 0x30);
usartSendChar(usart2, 'x');
usartSendChar(usart2, buffer[0]+0x30);
usartSendChar(usart2, buffer[1]+0x30);
print_Usart(usart2, "\n\r");
for(i = 0 ; i < 10 ; i++) {
delayMs(100);
pinToggle(pinB3);
delayMs(100);
}
*/
//timer_capture_compare_test(timer_2);
print_Usart(usart2, "All is working fine \r\n");
print_Usart(usart2, "All is working fine\n\r");
while(1) while(1)
{ {
delayMs(100);
pinToggle(pinB3);
delayMs(100);
} }
return 1; return 1;

Loading…
Cancel
Save