I think there was a bug with debug mode
Dependents: Generic_Platformer
MMA8452.cpp@1:ef026bf28798, 2013-10-08 (annotated)
- Committer:
- nherriot
- Date:
- Tue Oct 08 15:25:32 2013 +0000
- Revision:
- 1:ef026bf28798
- Parent:
- 0:bcf2aa85d7f9
- Child:
- 2:66db0f91b215
adding device id method detection
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nherriot | 0:bcf2aa85d7f9 | 1 | // Author: Nicholas Herriot |
nherriot | 0:bcf2aa85d7f9 | 2 | /* Copyright (c) 2013 Vodafone, MIT License |
nherriot | 0:bcf2aa85d7f9 | 3 | * |
nherriot | 0:bcf2aa85d7f9 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
nherriot | 0:bcf2aa85d7f9 | 5 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
nherriot | 0:bcf2aa85d7f9 | 6 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
nherriot | 0:bcf2aa85d7f9 | 7 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
nherriot | 0:bcf2aa85d7f9 | 8 | * furnished to do so, subject to the following conditions: |
nherriot | 0:bcf2aa85d7f9 | 9 | * |
nherriot | 0:bcf2aa85d7f9 | 10 | * The above copyright notice and this permission notice shall be included in all copies or |
nherriot | 0:bcf2aa85d7f9 | 11 | * substantial portions of the Software. |
nherriot | 0:bcf2aa85d7f9 | 12 | * |
nherriot | 0:bcf2aa85d7f9 | 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
nherriot | 0:bcf2aa85d7f9 | 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
nherriot | 0:bcf2aa85d7f9 | 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
nherriot | 0:bcf2aa85d7f9 | 16 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
nherriot | 0:bcf2aa85d7f9 | 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
nherriot | 0:bcf2aa85d7f9 | 18 | */ |
nherriot | 0:bcf2aa85d7f9 | 19 | |
nherriot | 0:bcf2aa85d7f9 | 20 | # include "MMA8452.h" |
nherriot | 0:bcf2aa85d7f9 | 21 | |
nherriot | 0:bcf2aa85d7f9 | 22 | |
nherriot | 0:bcf2aa85d7f9 | 23 | |
nherriot | 0:bcf2aa85d7f9 | 24 | float TILT_XY[64] = {0, 2.69, 5.38, 8.08, 10.81, 13.55, 16.33, 19.16, 22.02, 24.95, 27.95, 31.04, 34.23, 37.54, 41.01, 44.68, 48.59, 52.83, 57.54, 62.95, 69.64, 79.86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -79.86, -69.64, -62.95, -57.54, -52.83, -48.59, -44.68, -41.01, -37.54, -34.23, -31.04, -27.95, -24.95, -22.02, -19.16, -16.33, -13.55, -10.81, -8.08, -5.38, -2.69}; |
nherriot | 0:bcf2aa85d7f9 | 25 | float TILT_Z[64] = {90.00, 87.31, 84.62, 81.92, 79.19, 76.45, 73.67, 70.84, 67.98, 65.05, 62.05, 58.96, 55.77, 52.46, 48.99, 45.32, 41.41, 37.17, 32.46, 27.05, 20.36, 10.14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10.14, -20.36, -27.05, -32.46, -37.17, -41.41, -45.32, -48.99, -52.46, -55.77, -58.96, -62.05, -65.05, -67.98, -70.84, -73.67, -76.45, -79.19, -81.92, -84.62}; |
nherriot | 0:bcf2aa85d7f9 | 26 | |
nherriot | 0:bcf2aa85d7f9 | 27 | |
nherriot | 0:bcf2aa85d7f9 | 28 | |
nherriot | 0:bcf2aa85d7f9 | 29 | // Connect module at I2C address using I2C port pins sda and scl |
nherriot | 1:ef026bf28798 | 30 | Accelerometer_MMA8452::Accelerometer_MMA8452(PinName sda, PinName scl,int frequency) : m_i2c(sda, scl) , m_frequency(frequency) |
nherriot | 0:bcf2aa85d7f9 | 31 | { |
nherriot | 0:bcf2aa85d7f9 | 32 | //m_i2c.frequency(m_frequency); |
nherriot | 0:bcf2aa85d7f9 | 33 | } |
nherriot | 0:bcf2aa85d7f9 | 34 | |
nherriot | 0:bcf2aa85d7f9 | 35 | |
nherriot | 0:bcf2aa85d7f9 | 36 | // Destroys instance |
nherriot | 0:bcf2aa85d7f9 | 37 | Accelerometer_MMA8452::~Accelerometer_MMA8452() |
nherriot | 0:bcf2aa85d7f9 | 38 | { |
nherriot | 0:bcf2aa85d7f9 | 39 | |
nherriot | 0:bcf2aa85d7f9 | 40 | } |
nherriot | 0:bcf2aa85d7f9 | 41 | |
nherriot | 0:bcf2aa85d7f9 | 42 | // Setting the control register bit 1 to true to activate the MMA8452 |
nherriot | 0:bcf2aa85d7f9 | 43 | int Accelerometer_MMA8452::activate() |
nherriot | 0:bcf2aa85d7f9 | 44 | { |
nherriot | 1:ef026bf28798 | 45 | char mcu_address = (MMA8452_ADDRESS<<1); |
nherriot | 0:bcf2aa85d7f9 | 46 | char init[2]; |
nherriot | 0:bcf2aa85d7f9 | 47 | init[0] = CTRL_REG_1; // control register 1 |
nherriot | 0:bcf2aa85d7f9 | 48 | init[1] = 0x01; // set to active |
nherriot | 1:ef026bf28798 | 49 | //while(m_i2c.write(mcu_address,init,2)); |
nherriot | 1:ef026bf28798 | 50 | |
nherriot | 0:bcf2aa85d7f9 | 51 | if(m_i2c.write(mcu_address,init,2) == 0) |
nherriot | 0:bcf2aa85d7f9 | 52 | { |
nherriot | 0:bcf2aa85d7f9 | 53 | // pc.printf("The initialisation worked"); |
nherriot | 1:ef026bf28798 | 54 | return 0; // return 0 to indicate success |
nherriot | 0:bcf2aa85d7f9 | 55 | } |
nherriot | 0:bcf2aa85d7f9 | 56 | else |
nherriot | 0:bcf2aa85d7f9 | 57 | { |
nherriot | 0:bcf2aa85d7f9 | 58 | // pc.printf("The initialisation failed"); |
nherriot | 1:ef026bf28798 | 59 | return 1; // crumbs it failed!!! |
nherriot | 0:bcf2aa85d7f9 | 60 | } |
nherriot | 0:bcf2aa85d7f9 | 61 | |
nherriot | 0:bcf2aa85d7f9 | 62 | } |
nherriot | 0:bcf2aa85d7f9 | 63 | |
nherriot | 0:bcf2aa85d7f9 | 64 | |
nherriot | 0:bcf2aa85d7f9 | 65 | // Device initialization |
nherriot | 0:bcf2aa85d7f9 | 66 | void Accelerometer_MMA8452::init() |
nherriot | 0:bcf2aa85d7f9 | 67 | { |
nherriot | 0:bcf2aa85d7f9 | 68 | |
nherriot | 0:bcf2aa85d7f9 | 69 | write_reg(INTSU_STATUS, 0x10); // automatic interrupt after every measurement |
nherriot | 0:bcf2aa85d7f9 | 70 | write_reg(SR_STATUS, 0x00); // 120 Samples/Second |
nherriot | 0:bcf2aa85d7f9 | 71 | write_reg(MODE_STATUS, 0x01); // Active Mode |
nherriot | 0:bcf2aa85d7f9 | 72 | |
nherriot | 0:bcf2aa85d7f9 | 73 | } |
nherriot | 0:bcf2aa85d7f9 | 74 | |
nherriot | 0:bcf2aa85d7f9 | 75 | |
nherriot | 1:ef026bf28798 | 76 | // Get device ID |
nherriot | 1:ef026bf28798 | 77 | int Accelerometer_MMA8452::Get_DeviceID(int *deviceID) |
nherriot | 1:ef026bf28798 | 78 | { |
nherriot | 1:ef026bf28798 | 79 | char mcu_address = (MMA8452_ADDRESS<<1); |
nherriot | 1:ef026bf28798 | 80 | int z = 0; |
nherriot | 1:ef026bf28798 | 81 | m_i2c.start(); |
nherriot | 1:ef026bf28798 | 82 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 83 | if( m_i2c.write( mcu_address) == 0) |
nherriot | 1:ef026bf28798 | 84 | { |
nherriot | 1:ef026bf28798 | 85 | //printf( "GetDeviceId NAK on writing address"); |
nherriot | 1:ef026bf28798 | 86 | return 1; |
nherriot | 1:ef026bf28798 | 87 | } |
nherriot | 1:ef026bf28798 | 88 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 89 | if( m_i2c.write( WHO_AM_I) == 0) |
nherriot | 1:ef026bf28798 | 90 | { |
nherriot | 1:ef026bf28798 | 91 | //printf( "GetDeviceId NAK on writing register address"); |
nherriot | 1:ef026bf28798 | 92 | |
nherriot | 1:ef026bf28798 | 93 | return 1; |
nherriot | 1:ef026bf28798 | 94 | } |
nherriot | 1:ef026bf28798 | 95 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 96 | m_i2c.start(); |
nherriot | 1:ef026bf28798 | 97 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 98 | if( m_i2c.write( mcu_address | 0x01) == 0) // this is asking to read the slave address - even though it's a 'write' method!!! Crap API... |
nherriot | 1:ef026bf28798 | 99 | { |
nherriot | 1:ef026bf28798 | 100 | //printf( "GetDeviceId NAK on writing address"); |
nherriot | 1:ef026bf28798 | 101 | |
nherriot | 1:ef026bf28798 | 102 | return 1; |
nherriot | 1:ef026bf28798 | 103 | } |
nherriot | 1:ef026bf28798 | 104 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 105 | //deviceID = m_i2c.read(0); |
nherriot | 1:ef026bf28798 | 106 | z = m_i2c.read(0); |
nherriot | 1:ef026bf28798 | 107 | wait( 0.1); |
nherriot | 1:ef026bf28798 | 108 | m_i2c.stop(); |
nherriot | 1:ef026bf28798 | 109 | return 0; |
nherriot | 1:ef026bf28798 | 110 | |
nherriot | 1:ef026bf28798 | 111 | } |
nherriot | 1:ef026bf28798 | 112 | |
nherriot | 1:ef026bf28798 | 113 | |
nherriot | 0:bcf2aa85d7f9 | 114 | // Reads the tilt angle |
nherriot | 0:bcf2aa85d7f9 | 115 | void Accelerometer_MMA8452::read_Tilt(float *x, float *y, float *z) |
nherriot | 0:bcf2aa85d7f9 | 116 | { |
nherriot | 0:bcf2aa85d7f9 | 117 | |
nherriot | 0:bcf2aa85d7f9 | 118 | const char Addr_X = OUT_X_MSB; |
nherriot | 0:bcf2aa85d7f9 | 119 | char buf[3] = {0,0,0}; |
nherriot | 0:bcf2aa85d7f9 | 120 | |
nherriot | 0:bcf2aa85d7f9 | 121 | m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register |
nherriot | 0:bcf2aa85d7f9 | 122 | m_i2c.read(MMA8452_ADDRESS, buf, 3); // Read register content into buffer with 6bit |
nherriot | 0:bcf2aa85d7f9 | 123 | |
nherriot | 0:bcf2aa85d7f9 | 124 | // returns the x, y, z coordinates transformed into full degrees |
nherriot | 0:bcf2aa85d7f9 | 125 | *x = TILT_XY[(int)buf[0]]; |
nherriot | 0:bcf2aa85d7f9 | 126 | *y = TILT_XY[(int)buf[1]]; |
nherriot | 0:bcf2aa85d7f9 | 127 | *z = TILT_Z[(int)buf[2]]; |
nherriot | 0:bcf2aa85d7f9 | 128 | |
nherriot | 0:bcf2aa85d7f9 | 129 | } |
nherriot | 0:bcf2aa85d7f9 | 130 | |
nherriot | 0:bcf2aa85d7f9 | 131 | |
nherriot | 0:bcf2aa85d7f9 | 132 | // Reads x data |
nherriot | 0:bcf2aa85d7f9 | 133 | int Accelerometer_MMA8452::read_x() |
nherriot | 0:bcf2aa85d7f9 | 134 | { |
nherriot | 1:ef026bf28798 | 135 | char mcu_address = (MMA8452_ADDRESS <<1); |
nherriot | 0:bcf2aa85d7f9 | 136 | |
nherriot | 1:ef026bf28798 | 137 | m_i2c.start(); // Start |
nherriot | 1:ef026bf28798 | 138 | m_i2c.write(mcu_address); // A write to devic |
nherriot | 1:ef026bf28798 | 139 | m_i2c.write(OUT_X_LSB); // Register to read |
nherriot | 0:bcf2aa85d7f9 | 140 | m_i2c.start(); |
nherriot | 1:ef026bf28798 | 141 | m_i2c.write(mcu_address); // Read from device |
nherriot | 1:ef026bf28798 | 142 | int x = m_i2c.read(0); // Read the data |
nherriot | 0:bcf2aa85d7f9 | 143 | m_i2c.stop(); |
nherriot | 0:bcf2aa85d7f9 | 144 | |
nherriot | 1:ef026bf28798 | 145 | return x; |
nherriot | 0:bcf2aa85d7f9 | 146 | |
nherriot | 0:bcf2aa85d7f9 | 147 | } |
nherriot | 0:bcf2aa85d7f9 | 148 | |
nherriot | 0:bcf2aa85d7f9 | 149 | |
nherriot | 0:bcf2aa85d7f9 | 150 | // Reads y data |
nherriot | 0:bcf2aa85d7f9 | 151 | int Accelerometer_MMA8452::read_y() |
nherriot | 0:bcf2aa85d7f9 | 152 | { |
nherriot | 1:ef026bf28798 | 153 | char mcu_address = (MMA8452_ADDRESS <<1); |
nherriot | 0:bcf2aa85d7f9 | 154 | |
nherriot | 0:bcf2aa85d7f9 | 155 | m_i2c.start(); // Start |
nherriot | 0:bcf2aa85d7f9 | 156 | m_i2c.write(mcu_address); // A write to device 0x98 |
nherriot | 0:bcf2aa85d7f9 | 157 | m_i2c.write(OUT_Y_MSB); // Register to read |
nherriot | 0:bcf2aa85d7f9 | 158 | m_i2c.start(); |
nherriot | 0:bcf2aa85d7f9 | 159 | m_i2c.write(mcu_address); // Read from device 0x99 |
nherriot | 1:ef026bf28798 | 160 | int y = m_i2c.read(0); // Read the data |
nherriot | 0:bcf2aa85d7f9 | 161 | m_i2c.stop(); |
nherriot | 0:bcf2aa85d7f9 | 162 | |
nherriot | 1:ef026bf28798 | 163 | return y; |
nherriot | 0:bcf2aa85d7f9 | 164 | |
nherriot | 0:bcf2aa85d7f9 | 165 | } |
nherriot | 0:bcf2aa85d7f9 | 166 | |
nherriot | 0:bcf2aa85d7f9 | 167 | |
nherriot | 0:bcf2aa85d7f9 | 168 | // Reads z data |
nherriot | 0:bcf2aa85d7f9 | 169 | int Accelerometer_MMA8452::read_z() |
nherriot | 0:bcf2aa85d7f9 | 170 | { |
nherriot | 1:ef026bf28798 | 171 | char mcu_address = (MMA8452_ADDRESS <<1); |
nherriot | 0:bcf2aa85d7f9 | 172 | |
nherriot | 0:bcf2aa85d7f9 | 173 | m_i2c.start(); // Start |
nherriot | 0:bcf2aa85d7f9 | 174 | m_i2c.write(mcu_address); // A write to device 0x98 |
nherriot | 0:bcf2aa85d7f9 | 175 | m_i2c.write(OUT_Z_MSB); // Register to read |
nherriot | 0:bcf2aa85d7f9 | 176 | m_i2c.start(); |
nherriot | 0:bcf2aa85d7f9 | 177 | m_i2c.write(mcu_address); // Read from device 0x99 |
nherriot | 1:ef026bf28798 | 178 | int z = m_i2c.read(0); // Read the data |
nherriot | 0:bcf2aa85d7f9 | 179 | m_i2c.stop(); |
nherriot | 0:bcf2aa85d7f9 | 180 | |
nherriot | 1:ef026bf28798 | 181 | return z; |
nherriot | 0:bcf2aa85d7f9 | 182 | |
nherriot | 0:bcf2aa85d7f9 | 183 | } |
nherriot | 0:bcf2aa85d7f9 | 184 | |
nherriot | 0:bcf2aa85d7f9 | 185 | |
nherriot | 0:bcf2aa85d7f9 | 186 | // Reads xyz |
nherriot | 1:ef026bf28798 | 187 | int Accelerometer_MMA8452::read_xyz(char *x, char *y, char *z) |
nherriot | 1:ef026bf28798 | 188 | { |
nherriot | 1:ef026bf28798 | 189 | |
nherriot | 1:ef026bf28798 | 190 | |
nherriot | 1:ef026bf28798 | 191 | char mcu_address = (MMA8452_ADDRESS <<1); |
nherriot | 1:ef026bf28798 | 192 | char register_buffer[6] ={0,0,0,0,0,0}; |
nherriot | 1:ef026bf28798 | 193 | const char Addr_X = OUT_X_MSB; |
nherriot | 1:ef026bf28798 | 194 | m_i2c.write(mcu_address); // A write to device 0x98 |
nherriot | 1:ef026bf28798 | 195 | m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register |
nherriot | 1:ef026bf28798 | 196 | |
nherriot | 1:ef026bf28798 | 197 | if(m_i2c.write(mcu_address,&Addr_X,1) == 0) |
nherriot | 1:ef026bf28798 | 198 | { |
nherriot | 1:ef026bf28798 | 199 | if(m_i2c.read(mcu_address,register_buffer,6) == 0) |
nherriot | 1:ef026bf28798 | 200 | { |
nherriot | 1:ef026bf28798 | 201 | *x = register_buffer[1]; |
nherriot | 1:ef026bf28798 | 202 | *y = register_buffer[3]; |
nherriot | 1:ef026bf28798 | 203 | *z = register_buffer[5]; |
nherriot | 1:ef026bf28798 | 204 | return 0; // yahoooooo |
nherriot | 1:ef026bf28798 | 205 | } |
nherriot | 1:ef026bf28798 | 206 | else |
nherriot | 1:ef026bf28798 | 207 | { |
nherriot | 1:ef026bf28798 | 208 | return 1; // failed oh nooo! |
nherriot | 1:ef026bf28798 | 209 | } |
nherriot | 1:ef026bf28798 | 210 | } |
nherriot | 1:ef026bf28798 | 211 | else |
nherriot | 1:ef026bf28798 | 212 | { |
nherriot | 1:ef026bf28798 | 213 | return 1; // failed oh nooo! |
nherriot | 1:ef026bf28798 | 214 | } |
nherriot | 0:bcf2aa85d7f9 | 215 | |
nherriot | 1:ef026bf28798 | 216 | } |
nherriot | 0:bcf2aa85d7f9 | 217 | |
nherriot | 0:bcf2aa85d7f9 | 218 | // Write register (The device must be placed in Standby Mode to change the value of the registers) |
nherriot | 0:bcf2aa85d7f9 | 219 | void Accelerometer_MMA8452::write_reg(char addr, char data) |
nherriot | 0:bcf2aa85d7f9 | 220 | { |
nherriot | 0:bcf2aa85d7f9 | 221 | |
nherriot | 0:bcf2aa85d7f9 | 222 | char cmd[2] = {0, 0}; |
nherriot | 0:bcf2aa85d7f9 | 223 | |
nherriot | 0:bcf2aa85d7f9 | 224 | cmd[0] = MODE_STATUS; |
nherriot | 0:bcf2aa85d7f9 | 225 | cmd[1] = 0x00; // Standby Mode on |
nherriot | 0:bcf2aa85d7f9 | 226 | m_i2c.write(MMA8452_ADDRESS, cmd, 2); |
nherriot | 0:bcf2aa85d7f9 | 227 | |
nherriot | 0:bcf2aa85d7f9 | 228 | cmd[0] = addr; |
nherriot | 0:bcf2aa85d7f9 | 229 | cmd[1] = data; // New value of the register |
nherriot | 0:bcf2aa85d7f9 | 230 | m_i2c.write(MMA8452_ADDRESS, cmd, 2); |
nherriot | 0:bcf2aa85d7f9 | 231 | |
nherriot | 0:bcf2aa85d7f9 | 232 | cmd[0] = MODE_STATUS; |
nherriot | 0:bcf2aa85d7f9 | 233 | cmd[1] = 0x01; // Active Mode on |
nherriot | 0:bcf2aa85d7f9 | 234 | m_i2c.write(MMA8452_ADDRESS, cmd, 2); |
nherriot | 0:bcf2aa85d7f9 | 235 | |
nherriot | 0:bcf2aa85d7f9 | 236 | } |
nherriot | 0:bcf2aa85d7f9 | 237 | |
nherriot | 0:bcf2aa85d7f9 | 238 | |
nherriot | 0:bcf2aa85d7f9 | 239 | |
nherriot | 0:bcf2aa85d7f9 | 240 | // Read from specified MMA7660FC register |
nherriot | 0:bcf2aa85d7f9 | 241 | char Accelerometer_MMA8452::read_reg(char addr) |
nherriot | 0:bcf2aa85d7f9 | 242 | { |
nherriot | 0:bcf2aa85d7f9 | 243 | |
nherriot | 0:bcf2aa85d7f9 | 244 | m_i2c.start(); // Start |
nherriot | 0:bcf2aa85d7f9 | 245 | m_i2c.write(0x98); // A write to device 0x98 |
nherriot | 0:bcf2aa85d7f9 | 246 | m_i2c.write(addr); // Register to read |
nherriot | 0:bcf2aa85d7f9 | 247 | m_i2c.start(); |
nherriot | 0:bcf2aa85d7f9 | 248 | m_i2c.write(0x99); // Read from device 0x99 |
nherriot | 0:bcf2aa85d7f9 | 249 | char c = m_i2c.read(0); // Read the data |
nherriot | 0:bcf2aa85d7f9 | 250 | m_i2c.stop(); |
nherriot | 0:bcf2aa85d7f9 | 251 | |
nherriot | 0:bcf2aa85d7f9 | 252 | return c; |
nherriot | 0:bcf2aa85d7f9 | 253 | |
nherriot | 0:bcf2aa85d7f9 | 254 | } |
nherriot | 0:bcf2aa85d7f9 | 255 | |
nherriot | 0:bcf2aa85d7f9 | 256 | |
nherriot | 0:bcf2aa85d7f9 | 257 | |
nherriot | 0:bcf2aa85d7f9 | 258 | |
nherriot | 0:bcf2aa85d7f9 | 259 | |
nherriot | 0:bcf2aa85d7f9 | 260 |